如何从两个不同的中继连接中删除共享节点?

Posted

技术标签:

【中文标题】如何从两个不同的中继连接中删除共享节点?【英文标题】:How do I remove a shared node from two different relay connections? 【发布时间】:2021-11-02 03:15:22 【问题描述】:

我正在使用 Node 建立一个简单的 Relay/GraphQL 应用程序。

在根级别,我有一个名为“notes”的连接,它对数据库中的所有笔记进行分页。在我的用户对象上,我有一个注释连接,它对用户创建的所有注释进行分页。

  const rootNotesId = ConnectionHandler.getConnectionID('client:root', 'RootNotesConnection_notes');
  const userNotesId = ConnectionHandler.getConnectionID(queryData?.me?.id, 'UserNotesConnection_notes');
  
  const rootNotes = usePaginationFragment(graphql `
    fragment NotesRoot_notes on Query @refetchable(queryName: "NotesRootQuery") 
      notes(first: $count, after: $cursor) @connection(key: "RootNotesConnection_notes") 
        edges 
          node 
            ...Note_note
          
        
      
    
  `, queryData);
  
  const userNotes = usePaginationFragment(graphql`
    fragment NotesUser_notes on Query @refetchable(queryName: "NotesUserQuery") 
      me 
        id
        notes(first: $count, after: $cursor) @connection(key: "UserNotesConnection_notes") 
          edges 
            node 
              ...Note_note
            
          
        
      
    
  `, queryData);

如何在客户端同时向两个连接添加或删除注释?我有两种不同的边缘类型,我认为这段代码可以工作:

  const [commit, isInFlight] = useMutation(graphql `
    mutation NotesCreateMutation($input: createNoteInput!) 
      createNote(input: $input) 
        noteEdge 
          cursor,
          node 
            id
            user 
              username
            
            content
          
        
      
    
  `);
  
  const handleButtonClick = () => 
    if (!isInFlight) 
      commit(
        variables: 
          input: 
            content: newNoteInput
          
        ,
        updater: store => 
          const rootCon = ConnectionHandler.getConnection(store.get('client:root'), 'RootNotesConnection_notes');
          const userCon = ConnectionHandler.getConnection(store.get(userId), 'UserNotesConnection_notes');
          const payload = store.getRootField('createNote');
          const newEdge = payload.getLinkedRecord('noteEdge');
          const newNote = newEdge.getLinkedRecord('node');
          debugger;
          const newRootEdge = ConnectionHandler.createEdge(store, rootCon, newNote, 'QueryNotesEdge');
          const newUserEdge = ConnectionHandler.createEdge(store, userCon, newNote, 'UserNotesEdge');
          ConnectionHandler.insertEdgeAfter(rootCon, newRootEdge);
          ConnectionHandler.insertEdgeAfter(userCon, newUserEdge);
        
      );
      setNewNoteInput('');
    
  

我在调试中唯一能发现的是光标永远不会设置为新边缘。在调试器中单步执行这段代码会发现newRootEdge 之前的所有变量都可以正常解析

【问题讨论】:

【参考方案1】:

这行得通。感谢这个线程提供了一个很好的解决方法:https://github.com/facebook/relay/issues/2761

const handleButtonClick = () => 
    if (!isInFlight) 
      commit(
        variables: 
          input: 
            content: newNoteInput
          
        ,
        updater: store => 
          const rootCon = ConnectionHandler.getConnection(store.get('client:root'), 'RootNotesConnection_notes');
          const payload = store.getRootField('createNote');
          const newRootEdge = payload.getLinkedRecord('noteEdge');
          const prevRootEdges = rootCon.getLinkedRecords('edges');
          const nextRootEdges = [...prevRootEdges, newRootEdge];
          rootCon.setLinkedRecords(nextRootEdges, 'edges');
          
          const userCon = ConnectionHandler.getConnection(store.get(userId), 'UserNotesConnection_notes');
          const newNote = newRootEdge.getLinkedRecord('node');
          const newUserEdge = ConnectionHandler.createEdge(store, userCon, newNote, 'UserNotesEdge');
          newUserEdge.setValue(newRootEdge.getValue('cursor'), 'cursor');
          const prevUserEdges = userCon.getLinkedRecords('edges');
          const nextUserEdges = [...prevUserEdges, newUserEdge];
          userCon.setLinkedRecords(nextUserEdges, 'edges');
        
      );
      setNewNoteInput('');
    
  

【讨论】:

以上是关于如何从两个不同的中继连接中删除共享节点?的主要内容,如果未能解决你的问题,请参考以下文章

从 MySQL 中具有不同列的表的多个连接结果中删除重复项

设置石墨烯中继节点和连接字段的权限

如何使用匹配节点连接两个 XML 文件

阿里云经典网络和专有网络的区别

与 iptables 共享来自两个不同连接的互联网连接 [关闭]

如何使用 Azure WCF 中继和混合连接按钮?