这是一个描述如何使用纯 RxJS 完成此操作的答案。另一种选择是使用 NgRx。
首先,您设置了两个主题。目的是让所有组件都订阅它们并在刷新时接收最新数据?
你应该使用ReplaySubject
代替BehaviorSubject
不过,因为你没有任何初始状态。由于数据作为一件事返回,我会使用一个主题。
首先,我将声明一个接口,以便更容易讨论数据类型。
地震数据.ts
export interface EarthquakeData {
// TODO: create types for these
geometries: any[];
properties: any[];
}
在您的服务中,您可以通过自己的方法公开数据来分离检索和通知。
地震服务.ts
url = 'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson';
private _earthquakeData$ = new ReplaySubject<EarthquakeData>(1);
constructor(private readonly httpClient: HttpClient) {}
getEarthquakeData(): Observable<EarthquakeData> {
// return the subject here
// subscribers will will notified when the data is refreshed
return this._earthquakeData$.asObservable();
}
refreshEarthquakeData(): Observable<void> {
return this.httpClient.get<any>(this.url).pipe(
tap(response => {
// notify all subscribers of new data
this._earthquakeData$.next({
geometries: response.features.map(x => x.geometry),
properties: response.features.map(x => x.properties)
});
})
);
}
所以现在,所有想要接收数据的组件都将订阅一个方法:
private destroyed$ = new Subject();
ngOnInit()
this.earthquakeService.getEarthquakeData().pipe(
// it is now important to unsubscribe from the subject
takeUntil(this.destroyed$)
).subscribe(data => {
console.log(data); // the latest data
});
}
ngOnDestroy() {
this.destroyed$.next();
this.destroyed$.complete();
}
您可以在任意位置刷新数据:
refreshData() {
this.refreshing = true;
this.earthquakeService.refreshEarthquakeData().subscribe(() => {
this.refreshing = false;
});
}
DEMO: https://stackblitz.com/edit/angular-uv7j33