Angular observable 不会自动更新
Posted
技术标签:
【中文标题】Angular observable 不会自动更新【英文标题】:Angular observable not updating automatically 【发布时间】:2020-09-09 19:08:28 【问题描述】:我有一个服务,我向其传递了一个值,因此该值可供所有需要它的组件使用:
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
中的值。我错过了什么吗?
编辑---
所以在我的ngOnInit
中检查this.changeGroupService.getAnalysisStatus()
我可以看到result
的值实际上会根据需要进行更新,但模板不会更新以反映更改。
【问题讨论】:
【参考方案1】:看起来模板中呈现的值并不直接依赖于 observable 中的值。此外,变量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
运算符中使用 observable(这将在 ngOnDestroy
挂钩中完成)来避免内存泄漏问题。但是当多个组件中有多个订阅时,它可能会变得乏味。我在这里看到的这个问题有一个更好的解决方案:https://***.com/a/45709120/6513921。
【讨论】:
请问,在嵌套循环中调用detectChanges
肯定会影响性能,并可能产生意想不到的效果。考虑移到循环之外调用一次。另一件事我还没有测试过,但我相信如果您使用 map
或 reduce
重新创建数组,而不是使用 forEach
对其进行变异,您甚至不需要使用 ChangeDetectorRef
。
@developer033:这是一个有效的观点。我已经修改了代码。我也不确定使用map
/reduce
是否会触发默认更改检测。但这是个好主意。
离开组件后一定要销毁订阅,否则会出现内存泄漏。以上是关于Angular observable 不会自动更新的主要内容,如果未能解决你的问题,请参考以下文章
Angular 2 Firebase Observable 承诺不会返回任何东西
3 秒后自动关闭对话框 angular 5 observables
具有嵌套 Observable/FirebaseObjectObservable 的 Angular2 ngFor 在更新时闪烁一些数据