我正在为 GraphQL 服务器实现 Relay 样式分页,并使用优秀的 TypeORM 库。
我想找到在查询后创建 PageInfo 对象的最佳方法:
type PageInfo {
endCursor: String
hasNextPage: Boolean!
hasPreviousPage: Boolean!
startCursor: String
}
if (before) {
qb = qb.andWhere('note.notedAt <=(:before)', { before });
}
if (after) {
qb = qb.andWhere('note.notedAt >(:after)', { after });
}
qb = qb.take(args.take)
const [entities, totalEntitesCount] = qb.getManyWithCount()
有了这些信息,我们如何计算 hasNextPage
和 hasPreviousPage
我目前的想法:
function createPageInfo(
noteEdges: Array<{ node: Note; cursor: Date }>,
totalCount: number,
findOptions: NoteFindOptions
) {
let hasNextPage: boolean;
let hasPreviousPage: boolean;
if(findOptions.after) {
hasPreviousPage = true;
hasNextPage = (noteEdges.length < totalCount)
} else if (findOptions.before) {
hasNextPage = true;
hasPreviousPage = (noteEdges.length < totalCount)
} else {
hasPreviousPage = false;
hasNextPage = (noteEdges.length < totalCount)
}
return {
startCursor: noteEdges[0].cursor,
endCursor: noteEdges[noteEdges.length - 1].cursor,
hasNextPage,
hasPreviousPage
};
}
最佳答案
这几乎可以工作,但请记住 totalEntitiesCount
不是表中所有条目的计数,而是仅包含与光标条件匹配的条目( note.notedAt > :after
或 note.notedAt <= :before
)。 gb.getManyAndCount()
内部删除任何 orderBy、limit、skip 等,但保留 where 条件(请参阅 this file )。
如果在 before
上转发,也 IDK/after
光标确定hasNext
/hasPrev
分别就可以了。如果您将表中的第一个 ID 或日期传递给 after
您仍然会得到 hasPreviousPage = true
的光标但实际上不会有。
您可以在this gist中看到我对此的看法。 。这个想法是首先查询结果,然后为结果前后的totalCount和项目创建计数查询。在应用 where 条件之前克隆计数查询。这允许保留任何先前的条件但避免光标条件。作为奖励,您将获得下一个/上一个项目的计数。
它仍然是 WIP,我还没有测试过。
关于graphql - 使用 TypeORM getManyWithCount 如何生成用于分页的 PageInfo,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55301676/