将 Apollo 客户端用于 GraphQl 时如何在 watchQuery 中使用 loading 属性

Posted

技术标签:

【中文标题】将 Apollo 客户端用于 GraphQl 时如何在 watchQuery 中使用 loading 属性【英文标题】:How to use the loading property in a watchQuery when using the Apollo client for GraphQl 【发布时间】:2018-10-28 17:42:39 【问题描述】:

所以当我从查询中得到响应时,我可以看到有一个加载属性。但我真的不明白为什么他们会传递它。因为当你得到响应时,就意味着加载完成了,所以加载总是错误的。

有没有一种方法可以让我使用这个加载属性,以便我可以在调用仍在加载时显示加载图标?

我在 Angular 2 环境中有以下代码:

public apolloQuery = gql`
    query 
        apolloQuery 
    `;

const sub = this.apollo.watchQuery<QueryResponse>(
    query: this.apolloQuery 
).subscribe(data => 
    console.log(data);
    sub.unsubscribe();
);

并且来自数据对象的日志包含我所说的加载属性,这总是错误的。

我知道我可以创建自己的布尔属性并以这种方式检查,但我只是想知道是否可以使用 Apollo 提供的内置加载属性?

【问题讨论】:

【参考方案1】:

您的订阅有loading 参数:

import  Component, OnInit  from '@angular/core';
import  Apollo  from 'apollo-angular';
import gql from 'graphql-tag';

// We use the gql tag to parse our query string into a query document
const CurrentUserForProfile = gql`
  query CurrentUserForProfile 
    currentUser 
  login
  avatar_url

  
`;

@Component( ... )
class ProfileComponent implements OnInit, OnDestroy 
  loading: boolean;
  currentUser: any;

  private querySubscription: Subscription;

  constructor(private apollo: Apollo) 

  ngOnInit() 
    this.querySubscription = this.apollo.watchQuery<any>(
      query: CurrentUserForProfile
    )
      .valueChanges
      .subscribe(( data, loading ) => 
        this.loading = loading;
        this.currentUser = data.currentUser;
      );
  

  ngOnDestroy() 
    this.querySubscription.unsubscribe();
  

https://www.apollographql.com/docs/angular/basics/queries.html

【讨论】:

我明白,但它有什么用,更重要的是我该如何使用它?我看不出它的重要性,因为我自己可以更容易地做到这一点:拨打电话时,我将布尔值“加载”设置为 true,当我收到电话时,我将其设置回 false。 bu GraphQL 提供的布尔参数只有在调用完成后才对我可用,对吧? watchQuery 方法返回一个 QueryRef 对象,该对象的 valueChanges 属性是一个 Observable。我们可以看到结果对象包含加载,一个布尔值,指示查询是否“进行中”:github.com/apollographql/apollo-angular/blob/master/docs/source/… 有了这条评论,我知道加载参数在执行订阅时可用,而不是在调用完成时 @MartijnvandenBergh:您为什么将其标记为正确答案?它没有回答您的问题 - 正确答案由下面的 nanitohb 提供。 能否请您更新 apollo angular 网站中的参考链接【参考方案2】:

可以,需要设置选项notifyOnNetworkStatusChange: true,在这个documentation中有说明,然后使用loading prop:

this.querySubscription = this.apollo.watchQuery<any>(
  query: CurrentUserForProfile
  ,notifyOnNetworkStatusChange: true <-- This will make the trick
)
  .valueChanges
  .subscribe(( data, loading ) => 
    this.loading = loading; <-- now this will change to false at the start of the request
    this.currentUser = data.currentUser;
  );

【讨论】:

【参考方案3】:

这是 ApolloClient 3 中的 WatchQueryOptions

export interface WatchQueryOptions<TVariables> extends CoreWatchQueryOptions<TVariables> 
    /**
     * Observable starts with ` loading: true `.
     * There's a big chance the next major version will enable that by default.
     *
     * Disabled by default
     */
    useInitialLoading?: boolean;

这意味着您仍然需要明确告诉您希望收到“正在加载”状态更改标记的通知 (useInitialLoading: true),否则您只会得到错误。

const variables = ;
return apollo
   .watch(variables,  useInitialLoading: true )
   .valueChanges
   .subscribe((data, loading)=> console.log(loading)));

注意:如果仍然遇到问题,请使用a version greater than the 2.4

【讨论】:

以上是关于将 Apollo 客户端用于 GraphQl 时如何在 watchQuery 中使用 loading 属性的主要内容,如果未能解决你的问题,请参考以下文章

将 redux 客户端从 REST 转换为 GraphQL Apollo?

如何使用 apollo 客户端库创建带有角度参数的 graphql 查询

Apollo/graphQL:如何将乐观 UI 用于嵌套反应组件的突变?

在 reactJS 中使用动态字段的 Apollo 客户端 graphql 查询

使用 Apollo 客户端将文件上传到 GraphQL

GraphQL + Apollo 请求