我有一个用于编辑items
的EditItems
组件。在ngOnInit()
内部,我订阅了我dataService
中的可观察量(用于处理我所有数据调用的中央 Angular 服务(。
当可观察量的数据发生变化时,将调用我的subscribe
方法:
ngOnInit() {
this.myItemsSubscription = this.dataService.myItemsChanged
.subscribe(
(items: any[]) => {
let lastItem = items[items.length - 1];
if(lastItem.label.trim() === this.itemsForm.controls.label.value.trim()){
this.id = lastItem.id;
// *reference to 'this.editMode' below is always 'false'
if (this.editMode){
// do something
}
}
}
)
}
似乎在上面的subscribe
例程中,对当前组件中属性的任何引用都是指更改可观察量更改之前组件的状态。
例如,我稍后在ngOnInit
中设置this.editMode
的值,以便在检测到带有 id 参数的路由时将其设置为 'true',但是在上面的.subscribe
中,它仍然是 false(绝对没有其他东西可以将其设置回 false(。我已经验证this
肯定引用了我的组件。如果我将订阅之外的this.editMode
引用到this.dataService.myItemsChanged
中,我会得到正确的值true
。
this.route.params.subscribe((params: Params) => {
this.editMode = false;
if (Number(params['id']))
{
this.editMode = true;
}
this.initForm();
}
);
}
因此,当我导航到项目的路由时,对于现有的"项目",将触发上述订阅,并且this.editMode
设置为暂时true
,但是当在第一个subscribe
中引用"this.editMode"时,它会false
更新
当我创建新项目时,this
的属性仅引用"旧"值(新项目也是使用"EditItems"组件创建的(,然后导航到其他路由,然后导航回我的项目(路由上有"id",以便触发this.route.params.subscribe
(
这是我DataService
的相关部分。 我宣布myItemsChanged
主题为我的可观察对象。myItemsChanged
由单独的订阅更改,该订阅在项目更改时从后端侦听 SignalR 广播(itemUpdated
事件(
@Injectable()
export class DataService {
myItemsChanged = new Subject<any[]>();
//Listening for the 'itemUpdated' event broadcast by SignalR from the back end
let onItemUpdated$ = new BroadcastEventListener<any>('itemUpdated');
this.connection.listen(onItemUpdated$);
onItemUpdated$.subscribe((item: any) => {
let index = this.items.findIndex(x => x.id === item.id);
if (index > -1) {
this.myItemsChanged.next(this.items.slice());
}
});
为什么我在第一个订阅中看到this.editMode
价值的false
?
我没有取消订阅订阅,因此当我导航到另一个路由,然后返回到包含我的组件的路由时,我的订阅中存在对组件的某种不正确引用。
有关"何时取消订阅"的问题提供了导致此问题的原因的说明和答案:
Angular/RxJs 我什么时候应该取消订阅"订阅">
使用 Angular 路由时,导航到另一个路由会调用ngOnDestroy()
方法,并且该组件中的任何订阅都应在该方法中取消订阅,如下所示:
ngOnDestroy() {
this.myItemsSubscription.unsubscribe();
}
这可确保下次访问组件时重新订阅时不会出现内存泄漏或意外结果。