Angular Apollo中如何在Mutation内使用Refetch Query的响应结果?
How to Use Refetch Query Responses in Your Apollo Mutation (Angular)
嘿,我明白你的需求——你已经能用refetchQueries在账户创建成功后拉取更新后的列表,但现在想直接拿到这个refetch请求返回的数据来做后续处理。下面给你几种靠谱的实现方式:
方法1:通过Mutate返回的Observable获取Refetch结果
Apollo的mutate()方法返回的Observable里,其实已经包含了refetchQueries的执行结果,藏在additionalData字段里。你只需要订阅这个Observable就能拿到:
this.apollo.mutate({ mutation: mutationCreateNewAccount, variables: { accountNumber: this.accountNumber, accountType: this.accountType, routingNumber: this.routingNumber, nameOfAcountHolder: this.name }, refetchQueries: [ { query: YOUR_ACCOUNT_LIST_QUERY } // 替换成你实际的账户列表查询 ] }).subscribe((result) => { // 先拿到Mutation本身的返回数据 const newAccount = result.data.createNewAccount; // Refetch的结果是一个数组,和你refetchQueries里的查询顺序对应 if (result.additionalData && result.additionalData.length > 0) { const updatedAccountList = result.additionalData[0].data.accounts; // 这里就可以用更新后的列表做任何操作了,比如更新组件的数据源 this.accountList = updatedAccountList; console.log('最新账户列表:', updatedAccountList); } }, (error) => { console.error('创建账户或刷新列表失败:', error); });
注意:additionalData是按你refetchQueries的顺序排列的数组,如果你同时refetch多个查询,就按索引取对应的结果就行。
方法2:手动触发Refetch并处理结果
如果你觉得用additionalData不够直观,也可以在Mutation成功后,手动调用查询的refetch()方法,这样能更清晰地控制流程:
首先,在组件里先定义好你的账户列表查询(用watchQuery方便后续refetch):
// 组件类里的属性 private accountSub: Subscription; ngOnInit() { // 初始化监听账户列表查询 this.accountSub = this.apollo.watchQuery({ query: YOUR_ACCOUNT_LIST_QUERY }).valueChanges.subscribe(({ data }) => { this.accountList = data.accounts; }); }
然后在Mutation成功后手动触发refetch:
this.apollo.mutate({ mutation: mutationCreateNewAccount, variables: { accountNumber: this.accountNumber, accountType: this.accountType, routingNumber: this.routingNumber, nameOfAcountHolder: this.name } }).subscribe((mutationRes) => { // Mutation成功后,手动执行refetch this.apollo.watchQuery({ query: YOUR_ACCOUNT_LIST_QUERY }) .refetch() .subscribe((refetchRes) => { const updatedAccounts = refetchRes.data.accounts; // 这里直接用更新后的列表 this.accountList = updatedAccounts; console.log('手动刷新后的账户列表:', updatedAccounts); }); }, (err) => { console.error('创建账户失败:', err); }); // 记得在组件销毁时取消订阅,避免内存泄漏 ngOnDestroy() { this.accountSub.unsubscribe(); }
这种方式的好处是逻辑更清晰,你能明确控制refetch的时机,也能直接拿到完整的refetch响应。
方法3:用update函数直接修改缓存(更高效的替代方案)
如果你的需求只是更新本地的账户列表,其实不用重新发起请求——Apollo的update函数能直接修改缓存,性能更好,还能直接拿到修改后的数据:
this.apollo.mutate({ mutation: mutationCreateNewAccount, variables: { accountNumber: this.accountNumber, accountType: this.accountType, routingNumber: this.routingNumber, nameOfAcountHolder: this.name }, update: (cache, { data: { createNewAccount } }) => { // 先从缓存里读出现有的账户列表 const existingData = cache.readQuery({ query: YOUR_ACCOUNT_LIST_QUERY }); // 把新创建的账户加到列表里 const updatedAccounts = [...existingData.accounts, createNewAccount]; // 把更新后的列表写回缓存,UI会自动更新 cache.writeQuery({ query: YOUR_ACCOUNT_LIST_QUERY, data: { accounts: updatedAccounts } }); // 这里直接就能用updatedAccounts了 this.accountList = updatedAccounts; } }).subscribe((res) => { // 其他成功逻辑 }, (err) => { console.error('创建账户失败:', err); });
这种方法适合不需要从服务器拉取全量数据的场景,直接修改缓存就能同步UI,还省了一次HTTP请求。
小提示
- 使用
additionalData时,记得先判断它是否存在且不为空,避免报错 - 手动refetch时一定要管理好订阅,组件销毁时记得取消,防止内存泄漏
- 用
update函数时,要确保你的查询和Mutation返回的结构匹配,不然可能读/写缓存失败
内容的提问来源于stack exchange,提问作者Crazybud
相关产品推荐
相关产品推荐

