在服务中使用BehaviorSubject?

时间:2018-03-13 13:03:53

标签: angular rxjs behaviorsubject

我有服务,如下代码:

private caseListSource = new BehaviorSubject({});
caseList$ = this.caseListSource.asObservable();

loadCaseList() {
    return this._httpClient.get<Case>(environment.api_url +'/cases').do(data =>{
      this.caseListSource.next(data);

    });

在我的组件中,我正在执行以下操作:

caseList:any;

ngOnInit() {
   this.subscription = this._caseService.loadCaseList().subscribe(data => 
                                                                this.caseList = data);
  }

目前,我正在使用doBehaviorSubject上拨打下一个电话。有一个更好的方法吗?我应该在m订阅电话中拨打.next()吗?我会在每个想要通知的组件中调用next吗?

最初我没有使用BehaviorSubject,但是当我登录我的应用程序并转到select路由时,select组件中的ngOnInit将填充caseList和我也会在另一个组件中使用它。刷新case\2988之类的页面后,caseList将以未定义的形式返回。

2 个答案:

答案 0 :(得分:1)

为什么要创建3个不同的Observable?

private caseListSource = new BehaviorSubject({});是一个可观察者;

caseList$ = this.caseListSource.asObservable();是一个可观察者;

return this._httpClient.get<Case>(environment.api_url +'/cases')是另一个Observable;

只需在loadCaseList中返回http调用,您就可以看到http调用响应。类似的东西:

loadCaseList() {

  return this._httpClient.get<Case>(environment.api_url +'/cases');

}

如果您想维护Observable的副本,可以调用私有变量,例如:

loadCaseList() {

  this.caseListSource = this._httpClient.get<Case>(environment.api_url +'/cases');

  return this.caseListSource;

}

更新

似乎您正在使用BehaviorSubject为Observable提供初始值。

如果确实如此,您可以使用SwitchMap在组件初始化实例化BehaviorSubject和HTTP调用返回之间切换:

private caseListSource = new BehaviorSubject({}); // creates the behaviorSubject with an initial value

loadCaseList() {

  return this.caseListSource.switchMap(() => {

    return this._httpClient.get<Case>(environment.api_url +'/cases');

  });

}

通过这种方式,您可以获得初始值,然后在调用loadCaseList后切换到http调用。

答案 1 :(得分:0)

如果您只想在启动应用程序时发出一个请求,则BehaviorSubjects非常有用。

如果是这种情况,那么您的组件应订阅主题:

ngOnInit() {
   this.subscription = this._caseService.caseList$
     .subscribe(data => this.caseList = data);
}

如果您不关心提出多个请求,则不应使用它。

(这是我的意见和做事的方式,我可能是错的,所以不要把我的话用于绝对和唯一的真理)