如何在Apollo Client的watchQuery中使用loading属性?
如何利用Apollo Client内置的loading属性实现加载状态
嘿,我来帮你理清楚这个问题~你之所以看到loading属性始终为false,是因为当前的订阅方式只捕获到了请求完成后的最终结果,错过了Apollo Client在请求进行中发出的loading: true状态值。
问题根源
watchQuery返回的是一个Observable流,它会多次推送状态:
- 第一次:请求刚发起时,返回
{ loading: true, data: null } - 第二次:请求完成后,返回
{ loading: false, data: [你的查询结果] }
如果后续缓存有更新,它还会继续推送新的状态值。
你现在的代码里,订阅后立刻调用了sub.unsubscribe(),这会直接终止Observable流,导致你只拿到最后一次的完成状态,也就是loading: false的结果。
正确利用内置loading的方法
你可以把watchQuery的结果绑定到组件属性上,在模板中直接根据loading值控制加载图标的显示,完全不需要自己定义额外的布尔变量。
修改后的Angular代码示例:
import { Component, OnDestroy } from '@angular/core'; import { Apollo } from 'apollo-angular'; import gql from 'graphql-tag'; import { Subscription } from 'rxjs'; // 定义你的查询响应结构 interface QueryResponse { apolloQuery: any; } @Component({ template: ` <!-- 根据loading状态显示加载图标 --> <div *ngIf="queryResult.loading" class="loading-spinner">加载中...</div> <!-- 加载完成后渲染数据 --> <div *ngIf="!queryResult.loading && queryResult.data"> {{ queryResult.data.apolloQuery }} </div> ` }) export class YourComponent implements OnDestroy { apolloQuery = gql` query { apolloQuery } `; // 初始化默认状态为加载中 queryResult: { loading: boolean; data?: QueryResponse } = { loading: true }; private querySubscription: Subscription; constructor(private apollo: Apollo) { this.querySubscription = this.apollo.watchQuery<QueryResponse>({ query: this.apolloQuery }).subscribe(result => { this.queryResult = result; // 这里会打印两次:一次loading=true,一次loading=false带数据 console.log(result); }); } // 组件销毁时取消订阅,避免内存泄漏 ngOnDestroy() { this.querySubscription.unsubscribe(); } }
额外说明
如果你只需要单次请求(不需要监听缓存更新),可以使用query()方法,但它返回的是Promise,不会提供loading状态,这时候才需要自定义加载变量。而watchQuery是Apollo推荐的组件数据绑定方式,它天然支持实时的loading状态反馈,完全可以替代自定义的布尔属性。
内容的提问来源于stack exchange,提问作者Martijn van den Bergh
相关产品推荐
相关产品推荐

