【发布时间】:2019-10-27 03:26:15
【问题描述】:
大局,我想要实现的是一组过滤器我的页眉,它控制我应用程序中多个分析页面的输入参数。我已将过滤器的功能封装到一个 Angular 服务中,该服务公开了一个可观察的对象,当过滤器发生更改时会发出。
我想要的是在 HttpClient 请求中使用这些过滤器值的服务订阅过滤器中的更改并在过滤器更改时重新运行其 HttpClient 请求(因此,例如,如果日期范围发生更改,我页面上的任何元素由该日期范围驱动的数据会自动更新)。
我的应用中的典型数据服务如下所示。看起来我想要做的事情应该足够简单,但我正在努力让我的头脑充分了解 RxJS 库,以便按照我的目标组合可观察对象。
export class DashboardDataService {
constructor(
private readonly http: HttpClient,
private readonly globalFiltersService: GlobalFiltersService
) { }
public getDashboard(): Observable<DashboardDto> {
const filtersSubscription = globalFiltersService.filters$.subscribe(...);
const observable = this.http.get<DashboardDto>(`${environment.apiBase}network/dashboard`, {
params: this.globalFiltersService.getHttpParams()
});
// TODO: when filtersSubscription receives new data, make observable re-run it's HTTP request and emit a new response
return observable; // Make this observable emit new data
}
}
我使用的是 Angular 8 和 RxJS 6,所以最好采用最现代的方式。
更新:工作实施
export class GlobalFiltersService {
private readonly _httpParams$: BehaviorSubject<{ [param: string]: string | string[]; }>;
private start: Moment;
private end: Moment;
constructor() {
this._httpParams$ = new BehaviorSubject(this.getHttpParams());
}
public setDateFilter(start: Moment, end: Moment) {
this.start = start;
this.end = end;
this._httpParams$.next(this.getHttpParams());
}
public get httpParams$() {
return this._httpParams$.asObservable();
}
public getHttpParams() {
return {
start: this.start.toISOString(),
end: this.end.toISOString()
};
}
}
export class DashboardDataService {
private _dashboard$: Observable<DashboardDto>;
constructor(
private readonly http: HttpClient,
private readonly globalFiltersService: GlobalFiltersService
) { }
public getDashboard(): Observable<DashboardDto> {
if (!this._dashboard$) {
// Update the dashboard observable whenever global filters are changed
this._dashboard$ = this.globalFiltersService.httpParams$.pipe(
distinctUntilChanged(isEqual), // Lodash deep comparison. Only replay when filters actually change.
switchMap(params => this.http.get<DashboardDto>(`${environment.apiBase}network/dashboard`, { params })),
shareReplay(1),
take(1)
);
}
return this._dashboard$;
}
}
export class DashboardResolver implements Resolve<DashboardDto> {
constructor(private readonly dashboardDataService: DashboardDataService, private readonly router: Router) {}
public resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<DashboardDto> {
return this.dashboardDataService.getDashboard();
}
}
【问题讨论】:
标签: angular typescript rxjs angular-httpclient