graphql 突变如何自动刷新 Apollo Client 正在监视的查询?
How can a graphql mutation automatically refresh a query being watched by Apollo Client?
最近开始使用 graphQL 和 Apollo - apollo-client。
我在 graphQL 之上构建了一个网络服务,它工作得很好。我面临的唯一问题是在项目的客户端。例如(请参考下面的代码),在 运行 createVideo() 之后,我的组件的 data
属性 是一个观察查询的可观察对象,不会自动刷新并调用 apollo.query 手动回调似乎没有任何效果,因为查询 returns 缓存的结果,而不是来自服务器的结果。
我是不是漏掉了什么?
app.component.ts
import {Component, OnInit} from '@angular/core';
import {Apollo, ApolloQueryObservable} from 'apollo-angular';
import 'rxjs/Rx';
import gql from 'graphql-tag';
// http://dev.apollodata.com/angular2/mutations.html
const NewVideoQuery = gql`
mutation AddVideoQuery($title: String!,$duration: Int!, $watched: Boolean!){
createVideo(video: { title: $title, duration: $duration, watched: $watched } ){
id,
title
}
}
`;
const VideoQuery = gql`
{
videos {
id,
title
}
}
`;
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
data: ApolloQueryObservable<any>;
video: any = {};
constructor(private apollo: Apollo) {
}
ngOnInit() {
this.data = this.apollo.watchQuery({query: VideoQuery});
}
createVideo() {
/**
* This will send a mutate query to the server.
*/
// @todo After running the mutate, the watch query doesn't refresh
this.apollo.mutate({
mutation: NewVideoQuery,
variables: {
'title': this.video.title || 'Some Video' + Math.floor(Math.random() * 10),
'duration': 123213,
'watched': true
}
}).subscribe((afterMutation) => {
console.log(afterMutation);
// This fires but query doesn't hit the server since it's coming from cache.
// @todo Not even by re-running it here
this.apollo.query({query: VideoQuery})
.subscribe((data) => {
console.log(data);
});
}, (err) => alert(err));
}
}
//app.component.html
<div *ngFor="let x of data | async | select: 'videos'">
<div><b>{{x.id}}</b>{{x.title}}</div>
</div>
<label>
Title
<input type="text" [(ngModel)]="video.title">
</label>
<button (click)="createVideo()">{{title}}</button>
我明白了。
Apollo-client 默认情况下缓存我们的查询并且重新运行相同的查询当然 return 结果来自缓存而不是来自服务器。
自然地,因为我进行了修改以创建新记录,所以我希望服务器自动刷新数据集,但事实并非如此。
为了解决这个问题,我想出了重新 运行 我从 createVideo 突变的成功回调中查询的想法,但这次我添加了一个名为 fetchPolicy[= 的特殊选项29=] 支持以下值:
'cache-first' | 'cache-and-network' | 'network-only' | 'cache-only' | 'standby'
最后我的提取查询如下所示:
this.apollo.query({query: VideoQuery, fetchPolicy: 'network-only'})
.subscribe(()=>{ console.log('refresh done, our watchQuery will update') })
奖金提示:
Apollo 的另一个有趣的功能是您可以像这样设置一个池化间隔,这样您的数据始终与服务器同步
this.data = this.apollo.watchQuery({query: VideoQuery, pollInterval: 10000});
我建议您使用 fetchPolicy: 'cache-and-network',因为它会获取已存储的数据,还会更新缓存,使您的查询速度更快,但仍会更新缓存。您可以在此处阅读更多关于了解 Apollo Fetch 策略的信息 --> https://medium.com/@galen.corey/understanding-apollo-fetch-policies-705b5ad71980
最近开始使用 graphQL 和 Apollo - apollo-client。
我在 graphQL 之上构建了一个网络服务,它工作得很好。我面临的唯一问题是在项目的客户端。例如(请参考下面的代码),在 运行 createVideo() 之后,我的组件的 data
属性 是一个观察查询的可观察对象,不会自动刷新并调用 apollo.query 手动回调似乎没有任何效果,因为查询 returns 缓存的结果,而不是来自服务器的结果。
我是不是漏掉了什么?
app.component.ts
import {Component, OnInit} from '@angular/core';
import {Apollo, ApolloQueryObservable} from 'apollo-angular';
import 'rxjs/Rx';
import gql from 'graphql-tag';
// http://dev.apollodata.com/angular2/mutations.html
const NewVideoQuery = gql`
mutation AddVideoQuery($title: String!,$duration: Int!, $watched: Boolean!){
createVideo(video: { title: $title, duration: $duration, watched: $watched } ){
id,
title
}
}
`;
const VideoQuery = gql`
{
videos {
id,
title
}
}
`;
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
data: ApolloQueryObservable<any>;
video: any = {};
constructor(private apollo: Apollo) {
}
ngOnInit() {
this.data = this.apollo.watchQuery({query: VideoQuery});
}
createVideo() {
/**
* This will send a mutate query to the server.
*/
// @todo After running the mutate, the watch query doesn't refresh
this.apollo.mutate({
mutation: NewVideoQuery,
variables: {
'title': this.video.title || 'Some Video' + Math.floor(Math.random() * 10),
'duration': 123213,
'watched': true
}
}).subscribe((afterMutation) => {
console.log(afterMutation);
// This fires but query doesn't hit the server since it's coming from cache.
// @todo Not even by re-running it here
this.apollo.query({query: VideoQuery})
.subscribe((data) => {
console.log(data);
});
}, (err) => alert(err));
}
}
//app.component.html
<div *ngFor="let x of data | async | select: 'videos'">
<div><b>{{x.id}}</b>{{x.title}}</div>
</div>
<label>
Title
<input type="text" [(ngModel)]="video.title">
</label>
<button (click)="createVideo()">{{title}}</button>
我明白了。 Apollo-client 默认情况下缓存我们的查询并且重新运行相同的查询当然 return 结果来自缓存而不是来自服务器。
自然地,因为我进行了修改以创建新记录,所以我希望服务器自动刷新数据集,但事实并非如此。
为了解决这个问题,我想出了重新 运行 我从 createVideo 突变的成功回调中查询的想法,但这次我添加了一个名为 fetchPolicy[= 的特殊选项29=] 支持以下值:
'cache-first' | 'cache-and-network' | 'network-only' | 'cache-only' | 'standby'
最后我的提取查询如下所示:
this.apollo.query({query: VideoQuery, fetchPolicy: 'network-only'})
.subscribe(()=>{ console.log('refresh done, our watchQuery will update') })
奖金提示:
Apollo 的另一个有趣的功能是您可以像这样设置一个池化间隔,这样您的数据始终与服务器同步
this.data = this.apollo.watchQuery({query: VideoQuery, pollInterval: 10000});
我建议您使用 fetchPolicy: 'cache-and-network',因为它会获取已存储的数据,还会更新缓存,使您的查询速度更快,但仍会更新缓存。您可以在此处阅读更多关于了解 Apollo Fetch 策略的信息 --> https://medium.com/@galen.corey/understanding-apollo-fetch-policies-705b5ad71980