Angular 动态创建Apollo GraphQL变异调用
我的Angular应用程序中有一个工作的变异调用,用于使用Apollo GraphQL对对象的一些字段进行变异。变异调用的一部分包括一些返回数据,Apollo将这些数据与缓存中的某个对象关联,并用返回的新值更新它 我只想返回实际经过变异的字段,以避免通过网络发送大数据包。 我已经成功地动态生成了一个只包含被变异字段的变异文档,并将其传递到Angular 动态创建Apollo GraphQL变异调用,angular,graphql,apollo,Angular,Graphql,Apollo,我的Angular应用程序中有一个工作的变异调用,用于使用Apollo GraphQL对对象的一些字段进行变异。变异调用的一部分包括一些返回数据,Apollo将这些数据与缓存中的某个对象关联,并用返回的新值更新它 我只想返回实际经过变异的字段,以避免通过网络发送大数据包。 我已经成功地动态生成了一个只包含被变异字段的变异文档,并将其传递到apollo.mutate({mutation:newMutation,…}),它返回一个可观察的变量。突变只在可观察到的情况下触发。我已经验证了使用该订阅的组
apollo.mutate({mutation:newMutation,…})
,它返回一个可观察的变量。突变只在可观察到的情况下触发。我已经验证了使用该订阅的组件正在取消订阅并在调用新的变异之前被销毁
问题在于Apollo正在缓存变异文档,并为所有调用发送第一个变异(只有字段第一次变异)。我已通过检查我的web浏览器的“网络”选项卡验证了这一点。
我已经尝试过让阿波罗停止缓存它,方法是在datetime中添加唯一的突变名称。我已经检查过变异的变量是唯一的。我尝试过使用片段,但是片段也需要动态生成,这是相同的问题
有人知道我做错了什么吗?好吧,我知道了。Apollo客户端正在向其根目录添加变异文档。我发现使用Apollo客户端的writeData/writeQuery函数只能添加/修改根查询 最初,我试图动态地将字段添加到数据库中。代码如下所示:
import gql from 'graphql-tag';
...
const myMutation = gql`
mutation myMutation($id: ID!, ...) {
mutateFields(id: $id, ...) {
id # You need to return at least one field or it will complain
# Add mutated fields to return here
}
}
`;
# dynamically call the following lines based on fields to be added
myMutation.definitions[0].selectionSet.selections[0].selectionSet.selections = [
{...} # Added my own fields and their subfields here
];
问题是它第一次工作,所以我知道我正确地修改了GraphQL AST,但随后的调用(返回新字段)被正确创建,但Apollo发送了相同名称的第一个变体(我检查了浏览器的网络选项卡以验证)
解决方案:
不要修改GraphQL AST,而是将其修改为字符串文字,类似于Alireza Hariri在本文中的注释:
示例代码:
const mainMutation = `
mutation myMutation($id: ID!, ...) {
mutateFields(id: $id, ...) {
id # You need to return at least one field or it will complain
# REPLACE_THIS_WITH_FIELDS
}
}
`;
const mutationWithFields = mainMutation.replace(
`# REPLACE_THIS_WITH_FIELDS`,
"myField { mySubfield1 mySubfield2 }"
);
const finalMutation = gql`${mutationWithFields}`;
this.apollo.mutate({
mutation: finalMutation,
variables: {
id: myId,
...
}
});
准备-发送/接收密钥/val(写缓存)数组?Apollo客户端本身不会这样做。Apollo只缓存查询结果——它不缓存传递给它的DocumentNodes。您的代码中很可能还有其他原因导致了这种行为——如果您使用的不是HttpLink或者您在Apollo的API上编写的自定义包装器,那么可能是一个链接?