如何使用深度嵌套查询处理 Vue Apollo 中的删除?
Posted
技术标签:
【中文标题】如何使用深度嵌套查询处理 Vue Apollo 中的删除?【英文标题】:How do I handle deletes in Vue Apollo with deeply nested queries? 【发布时间】:2017-08-04 18:16:00 【问题描述】:我有一个查询,它返回多个嵌套对象以呈现一个充满信息的屏幕。我想删除一个深度嵌套的对象并乐观地更新屏幕(即不运行完整的查询)。
为了解释查询和 UI,我将使用类似 Trello board 的查询作为示例:
query everything
getBoard(id: "foo")
name
cardLists
edges
node
id
name
cards
edges
node
id
name
此查询的结果用于构建这样的 UI:https://d3uepj124s5rcx.cloudfront.net/items/170a0V1j0u0S2p1l290I/Board.png
我正在使用以下方式构建应用程序:
VueJS Vue 阿波罗 Scaphold.io 作为我的 GraphQL 商店当我想删除其中一张卡片时,我会调用:
deleteCard: function ()
this.$apollo.mutate(
mutation: gql`
mutation deleteCard($card: DeleteCardInput!)
deleteCard(input: $card)
changedCard
id
`,
variables:
'card':
id: this.id
,
)
.then(data =>
// Success
)
突变成功删除卡片,但我想根据突变立即更新 UI。执行此操作的简单选项是调用 refetchQueries: ['everything']
— 但这是一个昂贵的查询,而且对于快速 UI 更新来说太慢了。
我想做的是乐观地更新 UI,但是 Vue Apollo 的 example mutations 既没有解决删除问题,也没有解决深度嵌套的场景。
从深度嵌套的查询中删除项目并乐观地更新 UI 的正确解决方案/最佳实践是什么?
【问题讨论】:
如何在突变后更新查询,使用updateQueries
或 apollo 客户端的 dataIdFromObject
属性?
@Locco0_0 - 我正在使用updateQueries
。我是否可以使用dataIdFromObject
直接从商店中删除该对象,而不是更新查询?
是的,如果您向突变的返回值添加更深的嵌套,例如添加 cardLists 的 id 并在其中添加卡片。但它当然更慢。
【参考方案1】:
如果您查看 apollo 的 optimistic Response 的文档,您会发现乐观响应“伪造”了突变结果。
因此它将处理具有乐观值的updateQueries
函数。在您的情况下,这意味着如果您添加 optimisticResponse
属性,它应该使用乐观值更改 apollo 存储中的查询:
可能是这样的:
this.$apollo.mutate(
mutation: gql `
mutation deleteCard($card: DeleteCardInput!)
deleteCard(input: $card)
changedCard
id
`,
variables:
'card':
id: this.id
,
updateQueries:
// .... update Board
,
optimisticResponse:
__typename: 'Mutation',
deleteCard:
__typename: 'Card', // graphQL type of the card
id: this.id,
,
,
)
【讨论】:
谢谢。我不清楚的一点是如何编写updateQueries
,以便我可以非常有效地从现有查询中删除适当的节点,而不是再次重新查询整个板,这很慢。
我明白了。然后你可能想寻找reacts immutability helper。然后,您必须在深层嵌套查询中搜索正确的元素。看起来很硬
感谢指点,我去看看。我正在使用 Vue,但阅读 React 的不变性助手可能会帮助我了解情况。
与此同时,我意识到我可以轻松地在突变查询中加载父列表(以及子卡),让 Apollo 自动更新 UI。这仍然是一个过于昂贵的查询,但比重新加载整个董事会要好。
是的,我想加载这么多树的成本太高了。但正如你所说,总比重新取整板要好。以上是关于如何使用深度嵌套查询处理 Vue Apollo 中的删除?的主要内容,如果未能解决你的问题,请参考以下文章
Nuxt(Vue) 使用 $apollo.query 处理 Apollo 错误