中继现代嵌套分页

Posted

技术标签:

【中文标题】中继现代嵌套分页【英文标题】:Relay Modern nested pagination 【发布时间】:2018-05-21 20:16:00 【问题描述】:

我有一个songs 的根查询,它位于分页容器中。 然后,我有一个名为 comments 的歌曲的嵌套属性,我也希望对其进行分页,因为我不想一次为每首歌曲加载 10k cmets。

songsContainer.js:

fragment songsContainer on Query 
    songs(
      first: $count
      after: $cursor
      genre: $genre
      filter: $filter
    ) @connection(key: "songsContainer_songs") 
      edges 
        node 
          audioId
          name
          coverImageUrl
          artist
          likes
          dislikes
          ...commentsContainer
        
      
    
  

const connectionConfig = 
  direction: 'forward',
  query: graphql`
    query songsContainerForwardQuery(
      $count: Int!
      $cursor: String
      $genre: String
      $filter: FilterInput
    ) 
      ...songsContainer
    
  `,
  getVariables: (_,  count, cursor ) => (
    count,
    cursor,
  ),
;

paginationContainer(fragments, connectionConfig);

cmetsContainer.js

  fragment commentsContainer on Audio 
    comments(
      first: $count
      after: $cursor
      getReplies: $getReplies
    ) @connection(key: "commentsContainer_comments") 
      edges 
        node 
          commentId
          body
          date
          likes
          dislikes
          repliesCount
          originalComment 
            id
          
          user 
            userName
          
        
      
    
  

如何为 cmets 编写 connectionConfig?我试过这个:

const connectionConfig = 
  direction: 'forward',
  query: graphql`
    query commentsContainerForwardQuery(
      $count: Int!
      $cursor: String
    ) 
      ...commentsContainer
    
  `,
  getVariables: (_,  count, cursor ) => (
    count,
    cursor,
  ),
;

但是因为 cmets 嵌套在歌曲上,所以它会抛出一个错误,指出查询在 Root 上不存在。

【问题讨论】:

【参考方案1】:

SongsContainer.js

createPaginationContainer(
  SongsContainer,
  
    viewer: graphql`
      fragment SongsContainer_viewer on Query 
        id
        songs(first: $count, after: $cursor)
          @connection(key: "SongsContainer_songs", filters: []) 
          edges 
            cursor
            node 
              id
              ...SongItem_song
            
          
        
      
    `
  ,
  
    direction: 'forward',
    getConnectionFromProps(props) 
      return props.viewer && props.viewer.songs;
    ,
    getFragmentVariables(prevVars, totalCount) 
      return 
        ...prevVars,
        count: totalCount
      ;
    ,
    getVariables(props,  count, cursor , fragmentVariables) 
      return 
        count,
        cursor
      ;
    ,
    query: graphql`
      query SongsContainerQuery($count: Int!, $cursor: String) 
        viewer 
          ...SongsContainer_viewer
        
      
    `
  
);

SongItem.js

createRefetchContainer(
  SongItem,
  
    song: graphql`
      fragment SongItem_song on Audio
        @argumentDefinitions(
          count:  type: "Int", defaultValue: 20 
          cursor:  type: "String", defaultValue: null 
        ) 
        id
        ...CommentsContainer_song
        # ...more pagination container other_song
      
    `
  ,
  graphql`
    query SongItemQuery($id: ID!, $count: Int!, $cursor: String) 
      song(id: $id) 
        ...SongItem_song @arguments(count: $count, cursor: $cursor)
      
    
  `
);

CommentsContainer.js

createPaginationContainer(
  CommentsContainer,
  
    song: graphql`
      fragment CommentsContainer_song on Audio 
        id
        comments(first: $count, after: $cursor)
          @connection(key: "CommentsContainer_comments", filters: []) 
          edges 
            id
          
        
      
    `
  ,
  
    direction: 'forward',
    getConnectionFromProps(props) 
      return props.song && props.song.comments;
    ,
    getFragmentVariables(prevVars, totalCount) 
      return 
        ...prevVars,
        count: totalCount
      ;
    ,
    getVariables(props,  count, cursor , fragmentVariables) 
      return 
        count,
        cursor,
        id: props.song.id
      ;
    ,
    query: graphql`
      query CommentsContainerQuery($id: ID!, $count: Int!, $cursor: String) 
        song(id: $id) 
          ...CommentsContainer_song
        
      
    `
  
);

【讨论】:

以上是关于中继现代嵌套分页的主要内容,如果未能解决你的问题,请参考以下文章

仅手动中继现代运行 RefetchContainer

AddMutation 使用中继现代 graphql

中继 createFragmentContainer 的现代目的

在 QueryRenderer 中传递中继现代变量

中继现代碎片容器,道具不自动可用

中继现代片段错误(期望对象包含数据....)