【发布时间】:2017-09-06 08:30:20
【问题描述】:
我已经设置了一个“全局”服务,在我的 Angular 应用程序中跨组件共享参数:
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
@Injectable()
export class ParameterService {
param1 = new BehaviorSubject(null);
publishParam1(data: number) {
this.param1.next(data);
}
param2 = new BehaviorSubject(null);
publishParam2(data: number) {
this.param2.next(data);
}
}
需要这两个参数中的一个或两个的组件可以订阅,并在这些参数发生变化时得到通知:
private subscriptions: Array<Subscription> = [];
param1: number; // keep local copies of the params
param2: number;
ngOnInit(): void {
this.subscriptions.push(this._parameterService.param1.subscribe(
data => {
console.log("param1 changed: " + data);
if (data != null) {
this.param1 = data;
// NB! this.param2 may be undefined!
this.getDataFromAPI(this.param1, this.param2);
}
}
));
this.subscriptions.push(this._parameterService.param2.subscribe(
data => {
console.log("param2 changed: " + data);
if (data != null) {
this.param2 = data;
// NB! this.param1 may be undefined!
this.getDataFromAPI(this.param1, this.param2);
}
}
));
}
ngOnDestroy() {
// https://stackoverflow.com/questions/34442693/how-to-cancel-a-subscription-in-angular2
this.subscriptions.forEach((subscription: Subscription) => {
subscription.unsubscribe();
});
}
param1 和param2 由AppComponent 异步初始化,因此订阅两个 参数的组件将以任意顺序“通知”(接收值)。 getDataFromAPI 应该在任一参数更改时获取新数据,因此两个订阅都会调用该方法,但另一个参数可能仍然是 undefined。
显然,只需在调用 getDataFromAPI 之前检查是否定义了其他参数即可轻松解决此问题,但我想知道处理这种(肯定很常见)场景的最佳方法是什么? 我应该使用 promises 还是 await 来确保 getDataFromAPI 仅在定义了两个(所有)参数时才被调用?
想到的一个简单想法是确保ParameterService 只包含一个参数;即将param1 和param2 包装在一些“状态类”中:
export class StateObject {
param1: number;
param2: number;
constructor() { }
}
这样ParameterService就变成了,
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { StateObject } from './stateobject';
@Injectable()
export class ParameterService {
state = new BehaviorSubject(null);
publishState(data: StateObject) {
this.state.next(data);
}
}
【问题讨论】:
-
也许你应该使用 Observable.forkJoin,它会等到所有可观察对象完成并从每个对象发出最后一个值。
-
显然,在简单的解决方案中,组件不会知道 哪个 参数实际更改了,但在我的(特定)情况下,我将调用 API(刷新数据)每次一个或多个变化时使用所有参数。所以,它应该适用于我的场景,但可能方法太松懈了。
-
我想您可以将 if 子句
if(this.param2){this.getDataFromAPI(this.param1, this.param2); }添加到第一个订阅,将if(this.param1){this.getDataFromAPI(this.param1, this.param2); }添加到第二个订阅。这将确保getDataFromApi只有在两个参数都被定义的情况下才会被执行。 OfC 每次其中一个发生更改时,它都会执行所需的更新 -
是的,这就是我上面所描述的 :) 我正在寻找的是一个“更好的解决方案”,可能使用 promises 或 await。
标签: angular angular2-services behaviorsubject