Это ответ, описывающий, как это можно сделать, используя чистый Rx JS. Другой альтернативой является использование NgRx.
Во-первых, вы настроили два предмета. Предполагается, что все компоненты подпишутся на них и получат самые свежие данные после обновления?
Вы должны использовать ReplaySubject
вместо BehaviorSubject
, поскольку у вас нет начального состояния. И поскольку данные возвращаются как одна вещь, я бы использовал одну тему.
Во-первых, я собираюсь объявить интерфейс, чтобы было легче говорить о типах данных.
earthquake- data.ts
export interface EarthquakeData {
// TODO: create types for these
geometries: any[];
properties: any[];
}
В вашем сервисе вы можете разделить извлечение и уведомления, предоставив данные с помощью ваших собственных методов.
earthquake.service.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();
}
И вы можете sh обновить данные, где хотите:
refreshData() {
this.refreshing = true;
this.earthquakeService.refreshEarthquakeData().subscribe(() => {
this.refreshing = false;
});
}
ДЕМО: https://stackblitz.com/edit/angular-uv7j33