首页 > 解决方案 > 为什么 apollo 不为此查询调用我的 cacheRedirect?

问题描述

使用 apollo-angular,我有一个像这样的 apollo InMemoryCache

new InMemoryCache({
  // ... stuff

  cacheRedirects: {
    Query: {
      form: (_, args, { getCacheKey }) => {
        console.log('cache key', [args, getCacheKey({ __typename: 'Form', id: args.formId })]);
        return getCacheKey({ __typename: 'Form', id: args.formId });
      },
    },
  },
});

当我运行此查询时,form不会调用 cacheRedirect 函数。

this.apollo.watchQuery({
  query: gql`
    query FormSummary($formId: ID!) {
      form(formId: $formId) {
        __typename
        id
        description
      }
    }   
  `,
  variables: { formId }
}).valueChanges

相反,查询只是(成功地)进入服务器,忽略了表单(带有__typename、、iddescription字段)已经在缓存中的事实。即使它不在缓存中,我希望仍会调用表单的 cacheRedirect 函数。当我进行这个极其相似的查询时,会调用表单的 cacheRedirect 。

this.apollo.watchQuery<any>({
  query: gql`
    query FormGet($formId: ID!) {
      form(formId: $formId) {
        ...WholeFormResponse
      }
    }
    ${Fragments.wholeFormResponse}
  `,
  variables: { formId: id },
}).valueChanges

对于 cacheRedirects 的工作方式,我是否遗漏了一些明显的东西?我的印象query Form {}是,只要调用以开头的查询,cacheRedirect for 就form应该运行。

任何帮助是极大的赞赏!我想我错过了一些明显的东西......

注意:我对cacheRedirect的理解是fragment的内容WholeFormResponse是无关紧要的,所以我没有包含它们。

更新

打开调试器并单步执行一些代码,我的 cacheRedirect 函数没有被调用(在错误示例中)的原因是因为typeof fieldValue 在 apollo InMemoryCache 源代码的这一行中 !== 'undefined'。我还没有弄清楚为什么它应该是未定义的,或者为什么对于我的极其相似的工作查询它等于未定义。

标签: apolloapollo-clientapollo-angular

解决方案


经过 7 个小时的调试,我终于搞定了!!!!:D

原来这是一个 Angular 问题,而不是 Apollo 问题。两个查询(成功的一个和问题的一个)都在不同的角度服务中运行,这些服务本身就是不同 NgModules 的每个部分。这两个父 NgModule 都导入并定制了 apollo-angular ApolloModule。这导致了服务的两个独立实例Apollo

换句话说,我的 apollo 客户端(和缓存)不是单例服务,它是重复的!一项服务的查询缓存未共享/不可用于另一项服务,反之亦然。

无论如何,在清理完一切后,一切都按预期工作。


推荐阅读