使用尚不存在但已将所有信息存储在缓存中的查询从阿波罗缓存中读取查询

时间:2018-10-10 15:57:12

标签: vue.js graphql apollo-client

我有一个graphql端点,可以在其中输入此查询:

fragment ChildParts {
  id
  __typename
}

fragment ParentParts {
  __typename
  id
    children {
   edges{
       node {
         ...ChildParts 
       }
   }
}

query {
  parents {
    edges
      nodes {
        ...ParentParts
      }
    }
  }
}

执行后,它返回如下内容:

"data": {
  "edges": [
     "node": {
       "id": "<some id for parent>",
       "__typename": "ParentNode",
       "children": {
         "edges": [
           node: {
             "id": "<some id for child>",
             "__typename": "ChildNode"
           },
           ...
         ]
       }
     },
     ...   
  ]
}

现在,使用apollo客户端,在发生突变后,我可以从缓存中读取此查询,并更新/添加/删除任何ParentNode以及任何ChildNode,但是我必须遍历此查询返回的结构。< / p>

现在,我正在寻找一种从缓存中获取ChildNode列表的可能性(由于已将缓存作为平面列表创建,因此已经具有这些列表),从而使嵌套数据的更新更加容易。是否有可能从缓存中读取查询,而无需事先从服务器读取相同的查询?

1 个答案:

答案 0 :(得分:2)

您可以使用客户端的readFragment方法从缓存中检索任何一项。这只需要id和一个片段字符串。

const todo = client.readFragment({
  id,
  fragment: gql`
    fragment fooFragment on Foo {
      id
      bar
      qax
    }
  `,
})

请注意,id是dataIdFromObject函数返回的缓存键-如果您未指定自定义函数,则(假设存在__typename和id或_id字段)默认实现只是:

${result.__typename}:${result.id || result._id}

如果提供了自己的dataIdFromObject函数,则需要提供该函数返回的ID。

正如@Herku所指出的,根据用例,在解决另一个查询时,也可以使用缓存重定向来利用为一个查询缓存的数据。这是设置InMemoryCache的一部分:

const cache = new InMemoryCache({
  cacheRedirects: {
    Query: {
      book: (_, args, { getCacheKey }) =>
        getCacheKey({ __typename: 'Book', id: args.id })
    },
  },
})

不幸的是,截至撰写此答案时,我不相信有任何方法可以通过id删除缓存的项目。关于这一点,正在进行讨论here(原始问题here)。