GraphQL Relay hasNextPage

时间:2016-04-05 21:50:49

标签: graphql relay graphql-js

如果仅传递“first”参数,graphql如何生成hasNextPage? 我正在使用

return relay.connectionFromPromisedArray( global.app.get('model__user').getUsers(args), args );

和查询:

query RootQueryType { viewer { user(id: 1){ id,email,friends(first: 5) {edges {cursor, node { id, email } }, pageInfo { hasNextPage } } } } }

那么我怎样才能传递给graphql / relay朋友计数,以便生成正确的hasNextPage?

2 个答案:

答案 0 :(得分:1)

中继分页不是基于页面的,而是基于fn fetch。因此,您通过说"我希望在项目Y"之后的X项目进行分页。项目Y不是指向页码或偏移量,而是指向该确切对象的指针,即所谓的游标。这种分页模型很适合,例如,无限滚动。 "页"添加或删除项目后也会保持稳定,因为它们不依赖于项目数量。

Relay GraphQL规范中的

cursor仅指示在检索到的最后一个元素之后是否还有更多项。因此,在您的情况下,这意味着总共有超过5个元素,如果您这样做,您将获得更多元素

hasNextPage

您可以从friends(first: 5, after: "CURSOR_TO_THE_LAST_ELEMENT") 列表中检索光标,它是edges旁边的元素之一。

答案 1 :(得分:1)

您可以在此处找到有关中继分页算法的详细信息:https://facebook.github.io/relay/graphql/connections.htm#sec-Pagination-algorithm

要回答有关hasNextPage的具体问题,请使用以下算法:

function hasNextPage(allEdges, before, after, first, last) {

    // If first was not set, return false.
    if (first === null) { return false; }

    // Apply the before & after cursor arguments to the set of edges.
    // i.e. edges is the set of edges between the before and after cursors
    const edges = ApplyCursorsToEdges(allEdges, before, after)

    // If more edges exist between the before & after cursors than
    // you are asking for then there is a next page.
    if (edges.length > first) { return true; }
    return false
}

关于光标与基于页面的分页的快速说明。使用固定页面大小进行分页通常是个坏主意。一个典型的例子就是在SQL中使用OFFSET关键字来获取下一页。这种方法存在许多问题。例如,如果在对集合进行分页的过程中插入了新对象会发生什么?如果在您当前抓取的页面之前插入了新对象,并且使用固定偏移量,则您将抓取已经抓取的对象,这会导致表示层中出现重复数据。使用游标进行分页可以通过允许您跟踪对象本身而不是对象的计数来解决此问题。

特别是继电器分页的最后一件事。我建议在任何给定时间仅使用(第一次和之后)OR(最后和之前)。在同一查询中使用两者可能会产生逻辑但意外的结果。

祝你好运!