Angular observable 不会自动更新
Angular observable not updating automatically
我有一项服务,我向其传递了一个值,因此该值可供所有需要它的组件使用:
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
的值实际上是根据需要更新,但模板不会更新以反映更改。
模板中呈现的值似乎并不直接依赖于可观察值。此外,变量 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
挂钩中完成)以避免内存泄漏问题。但是当多个组件中有多个订阅时,它可能会变得乏味。对于我在这里看到的这个问题,有一个更好的解决方案:.
我有一项服务,我向其传递了一个值,因此该值可供所有需要它的组件使用:
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
的值实际上是根据需要更新,但模板不会更新以反映更改。
模板中呈现的值似乎并不直接依赖于可观察值。此外,变量 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
挂钩中完成)以避免内存泄漏问题。但是当多个组件中有多个订阅时,它可能会变得乏味。对于我在这里看到的这个问题,有一个更好的解决方案: