如何处理具有多个参数(例如表格数据)的查询的Apollo缓存更新

时间:2019-02-24 17:50:12

标签: vue.js graphql apollo apollo-client vue-apollo

我的问题的简要摘要

我有一个getTracks查询,它将获取跟踪数据,并接受一些用于排序/过滤的参数(限制,偏移,搜索,排序,顺序)。不幸的是,Apollo单独缓存了所有这些内容,因此,在一个视图中删除某项时,用户会更改排序顺序,而删除的项仍在那里(因为它在缓存中用于一组不同的参数)。

详细信息

这是getTracks查询以及相关的输入类型(在我的服务器端AppSync模式中):

input SelectOptions {
  limit: Int
  offset: Int
  sort: String
  order: String
  search: String
}

type Query {
  getTracks(options: SelectOptions): TrackList!
}

type TrackList {
  total: Int!
  items: [Track!]!
}

在Vue客户端中,查询如下:

query GetTracks($options: SelectOptions) {
  getTracks(options: $options) {
    total
    items {
      id
      name
      runtime
      createdAt
      metadata {
        trackNum
        trackName
        artistName
        albumName
        year
      }
    }
  }
}

第一次显示该表时,项目会加载并显示良好(默认排序顺序是在At / desc中创建的)。如果我按createdAt / asc排序,则会发出网络请求以获取结果,并且显示效果很好。现在,如果我删除其中一条记录,然后再次按createdAt / desc进行排序,则会显示已删除的项目,因为它是从缓存中提取该项目的。

即使查询具有不同的参数,Apollo中也没有办法使它智能地通过并从缓存中删除(或添加/修改)项目吗?我确实尝试过@connection指令as documented here,但这只是使表排序没有效果(根本无法从服务器获取)。

我完全陷入了困境,并准备完全禁用缓存,因为它在现实世界中似乎不起作用。如何保留默认的cache-and-network策略,但在更改数据时使我的表正常运行?

1 个答案:

答案 0 :(得分:0)

不幸的是,this issue has been brought up before并没有很好的解决方案。最大的问题是客户端和缓存都不会公开用于获取给定查询的所有请求的任何方法-如果您具有该信息,则可以遍历请求并适当地更新缓存。

接下来要做的第二件事是利用apollo-link-watched-mutation。该链接使我们可以有效地识别每个突变将需要更新的一个或多个查询,但是它使用操作名称来识别查询(以及哪些突变应触发它们)。这样,您甚至不需要知道相关变量即可更新查询-您只需要一致地命名操作即可。

new WatchedMutationLink(
  cache,
  {
    SaveTodo: {
      TodoList: ({ mutation, query }) => {
        // update logic here
      }
    }
  }
)

此方法的一个缺点是,您失去了基于每个组件定义update逻辑的能力。但是,您也可以通过使用不同命名的突变来解决该限制。