Apollo缓存+自动刷新

Posted

技术标签:

【中文标题】Apollo缓存+自动刷新【英文标题】:Apollo cache + automatic refresh 【发布时间】:2019-07-05 03:53:53 【问题描述】:

我有一个从 GraphQL 服务器访问数据的 Angular 7 应用程序。

我直接实现了文档中的示例: https://www.apollographql.com/docs/react/advanced/caching.html#automatic-updates

这是获取 post 对象并执行 upvote 突变的服务。

export class PostService 

  constructor(private apollo: Apollo)  

  public getPost() 
    return this.apollo.query(
      query: gql`query getPost($id: String!) 
        post(id: $id) 
          id
          score
        
      `,
      variables:  id: '123' 
    );
  

  public upvote() 
    return this.apollo.mutate(
      mutation: gql`mutation upvote($id: String!) 
        upvotePost(id: $id) 
          id
          score
        
      `,
      variables:  id: '123' 
    );
  

在我的 component.ts 文件中

  public post = this.postService.getPost();
  public vote() 
    this.postService.upvote().subscribe(console.log);
  

在我的 component.html 中

    <input type="text" [value]="(post | async).data.post.score" />
    <button class="button" (click)="vote()"></button>

框中的值不会改变。

如果我添加一个额外的按钮来调用这个函数

public updateView() 
  post = this.postService.getPost();

gui 将在不查询服务器的情况下更新,因此很明显来自缓存。

根据规范,此手动刷新步骤是不必要的。

If the id field on both results matches up, then the score field everywhere in our UI will be updated automatically!

我的包的版本:

阿波罗角度:1.5.0 apollo-angular-link-http:1.4.0 apollo-angular-link-http-common: 1.4.0 阿波罗缓存:1.1.25 apollo-cache-inmemory:1.4.2 apollo 客户端:2.4.12

我需要更改什么,以便在原始请求返回的 observable 中实际更新结果?

或者我只是不了解预期的机制?

【问题讨论】:

你正在编写一个 Angular 应用程序,但你已经发布了 React Apollo 客户端的文档? 既然你提到它... :( 【参考方案1】:

现在我使用了文档的角度部分而不是 React 部分,我找到了解决方案。 (@tombraider 感谢您将我推向正确的方向。)

我需要使用watchQuery,而不是query

  public getPost(id: string) 
    return this.apollo.watchQuery(
      query: gql`query getPost($id: String!) 
        post(id: $id) 
          id
          score
        
      `,
      variables:  id 
    ).valueChanges;
  

服务功能的这个更改版本不断更新 GUI。

【讨论】:

【参考方案2】:

这里有点疯狂的猜测,但我建议这是因为您没有编写内联查询;文档会有所不同。看看你可以传递给你的 Mutation 的 refetchQueries 属性,即

  public upvote() 
    return this.apollo.mutate(
      mutation: gql`mutation upvote($id: String!) 
        upvotePost(id: $id) 
          id
          score
        
      `,
      variables:  id: '123' ,
      refetchQueries: [],
    );

当你的突变执行时,你告诉 GraphQL 你想执行你在refetchQueries 数组中提供的查询。因此,缓存将更新。但是,我不是 100% 相信您的查询会执行,因为您在技术上没有订阅它,您所做的只是执行一次性承诺以从 GraphQL 端点获取数据。

【讨论】:

一次性承诺不是 Promise 而是 Observable。它可能仍然是“一次”。正如我之前所描述的,缓存在突变后已经更新了,但是这个变化并没有反映在 GUI 中。

以上是关于Apollo缓存+自动刷新的主要内容,如果未能解决你的问题,请参考以下文章

如何自动刷新 SQL Server Management Studio 智能感知缓存?

如何在打开网页时自动刷新一次?只要一次!

Javascript实现页面加载完成后自动刷新一遍清除缓存文件

Apollo 配置中心

打开页面自动刷新网页,自动刷新当前页面,JS调用

使用 SCF 自动刷新被 CDN 缓存的 COS 资源