graphql:如何正确处理上一页,下一页,最后一页和第一页?
Posted
技术标签:
【中文标题】graphql:如何正确处理上一页,下一页,最后一页和第一页?【英文标题】:graphql: how to handle prev page, next page, last page and first page properly? 【发布时间】:2019-03-07 04:08:51 【问题描述】:对于前端,我使用 React + Relay。我在后端有一些可以像这样查询的连接:
query Query
node(id: 123456)
teams(first: 10)
node
id
name
page_info
start_cursor
end_cursor
所以对于传统的方法,我可以使用skip PAGE_SIZE * curr limit PAGE_SIZE
来查询下一页、上一页和第一页和最后一页(实际上我可以查询随机页)
但是我应该如何实现前端来优雅地发出这些请求呢?
【问题讨论】:
您的架构似乎不符合中继规范。您应该拥有myConnection.edges.node
、myConnection.pageInfo
而不是page_info
。您可能想查看 createPaginationContainer 的示例。 facebook.github.io/relay/docs/en/…
【参考方案1】:
@Junchao,文森特说的是对的。此外,您必须重新获取查询并发送 refetchVariables
并更新您的 first
值。我会尽量给你举个例子:
export default createRefetchContainer(
TeamsComponent,
query: graphql`
fragment TeamsComponent_query on Query
@argumentDefinitions(
first: type: Int
last: type: Int
before: type: String
after: type: String
)
teams(
id: type: "ID!"
first: type: Int
last: type: Int
before: type: String
after: type: String
) @connection(key: "TeamsComponent_teams", filters: [])
count
pageInfo
endCursor
hasNextPage
edges
node
id
name
`,
,
graphql`
query TeamsComponent(
$after: String
$before: String
$first: Int
$last: Int
)
...TeamsComponent_query
@arguments(
first: $first
last: $last
after: $after
before: $before
)
`,
);
我尝试根据您的代码构建一个示例。基本上是这个想法。底部查询是重新获取的查询。除此之外,您必须通过调用this.props.relay.refetch
传递您的renderVaribles
以某种方式触发此重新获取。深入了解有关此的文档。
希望有帮助:)
更新:
只是为了添加一些东西,你可以有一个 handleLoadMore
函数,像这样:
handleLoadMore = () =>
const relay, connection = this.props;
const isFetching = this.state;
if (!connection) return;
const edges, pageInfo = connection;
if (!pageInfo.hasNextPage) return;
const total = edges.length + TOTAL_REFETCH_ITEMS;
const fragmentRenderVariables = this.getRenderVariables() || ;
const renderVariables = first: total, ...fragmentRenderVariables ;
if (isFetching)
// do not loadMore if it is still loading more or searching
return;
this.setState(
isFetching: true,
);
const refetchVariables = fragmentVariables => (
first: TOTAL_REFETCH_ITEMS,
after: pageInfo.endCursor,
);
relay.refetch(
refetchVariables,
null,
() =>
this.setState( isFetching: false );
,
force: false,
,
);
;
更新 2:
对于倒退,你可以有类似的东西:
loadPageBackwardsVars = () =>
const connection, quantityPerPage = this.props;
const quantity = getFormatedQuery(location);
const endCursorOffset, startCursorOffset = connection;
const firstItem = connection.edges.slice(startCursorOffset, endCursorOffset)[0].cursor;
const refetchVariables = fragmentVariables => (
...fragmentVariables,
...this.getFragmentVariables(),
last: parseInt(quantity || quantityPerPage, 10) || 10,
first: null,
before: firstItem,
);
return refetchVariables;
;
【讨论】:
谢谢你的详细答案——虽然我认为你给出的例子仍在获取下一页,对吗?上一页、第一页和最后一页呢? 不确定是否可以提供所有示例和案例,但我更新了一个倒退的想法。 非常感谢您的帮助——我可以仔细看看容器。但似乎从根本上说,这个想法就是我现在正在做的事情。操纵不同的变量 在我看来,Relay 非常难。我仍然没有完全理解它,但同时,我认为它非常强大。祝你好运:)以上是关于graphql:如何正确处理上一页,下一页,最后一页和第一页?的主要内容,如果未能解决你的问题,请参考以下文章
winform中的DataGridView如何实现分页(C#)