角度可观察不会自动更新

时间:2020-05-22 20:43:18

标签: angular observable behaviorsubject

我有一个将值传递给的服务,因此该值可用于需要它的所有组件:

  setAnalysisStatus(statuses: AsyncAnalysis[]) {
    this.analysisStatus.next(statuses);
  }

我有一个通过单击按钮显示的组件。显示的组件调用另一种方法来订阅analysisStatus

  getAnalysisStatus(): Observable<AsyncAnalysis[]> {
    return this.analysisStatus.asObservable();
  }

该组件的订阅如下:

ngOnInit(){
this.changeGroupService.getAnalysisStatus()
.subscribe(result => {
  result.forEach(item => {
    this.changeGroupStatus.forEach((changeGroup, index) => {
      if (item.changeGroupId === changeGroup.id) {
        this.changeGroupStatus[index].name = this.changeGroupStatus[index].name;
        this.changeGroupStatus[index].status = item.status;
      }
    });
  });
});
}

当我触发该组件时,它将显示analysisStatus的当前状态。但是,当状态改变时,组件不会更新。如果我关闭然后重新打开该组件,它将显示新状态。我需要它来显示状态并在analysisStatus的状态更改时进行更新。

analysisStatus的设置如下:

analysisStatus = new BehaviorSubject<AsyncAnalysis[]>([]);

我的假设是通过this.changeGroupService.getAnalysisStatus()进行订阅,应该寻找更新this.changeGroupStatus中的值。我想念什么吗?

编辑---

因此,在this.changeGroupService.getAnalysisStatus()中检查ngOnInit可以看到result的值实际上是根据需要更新的,但是模板不会更新以反映更改。

1 个答案:

答案 0 :(得分:1)

看来模板中呈现的值不直接取决于可观察值。另外,变量changeGroupStatus没有分配新值。它只有几个属性被更改。 Angular可能无法检测到部分更改。在这种情况下,您可以尝试使用ChangeDetectorRef手动触发更改检测。尝试以下

import { pipe, Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

destroyed = new Subject<void>();

ngOnInit(){
  this.changeGroupService.getAnalysisStatus().pipe(
    takeUntil(this.destroyed)
  ).subscribe(result => {
      result.forEach(item => {
        this.changeGroupStatus.forEach((changeGroup, index) => {
          if (item.changeGroupId === changeGroup.id) {
            this.changeGroupStatus[index].name = this.changeGroupStatus[index].name;
            this.changeGroupStatus[index].status = item.status;
          }
        });
      });
      this.cdr.detectChanges();           // <-- trigger change detection here
    });
}

ngOnDestroy(): void {
  this.destroyed.next();
  this.destroyed.complete();
}

更新

您可以在takeUntil运算符中使用可观察的管道(将在ngOnDestroy挂钩中完成)以避免内存泄漏问题。但是,当多个组件中存在多个订阅时,可能会变得乏味。我在这里看到的这个问题有一个更好的解决方案:https://stackoverflow.com/a/45709120/6513921