首页 > 解决方案 > 组件被销毁后,可观察订阅保持活动状态

问题描述

我的一个组件订阅路由器事件,如下所示:

    this.navigationSubscription = this.router.events.subscribe((e: any) => {
      // If it is a NavigationEnd event re-initalise the component
      if (e instanceof NavigationEnd) {
        let p = e as NavigationEnd;
          console.log(p.urlAfterRedirects);
        console.log("im being called from NavigationEnd");
        this.ngOnInit();
      }
    });
   }

当用户通过按钮第二次导航到组件时,我使用此代码重新加载组件。在调试问题时,我注意到当我导航到另一个组件时,这段代码仍然保持活动状态,即使它所属的组件不是。有人可以解释即使组件本身不再存在,此代码为何以及如何保持活动状态?当代码无法到达时,它不应该导致错误this.ngOnInit()吗?

我可以通过在 onDestroy 方法中取消订阅来解决这个问题,但我真的很想知道当组件不再存在时代码如何保持活动状态,以及为什么this.ngOnInit()不抛出错误,因为组件不活动.

标签: angular

解决方案


一般来说,组件销毁后,所有订阅都保持活动状态。

这是 Angular IMO 的一大痛点。

但是,此规则有一些例外情况:

  • this.activatedRoute.params.subscribe - 自动取消订阅
  • this.activatedRoute.data.subscribe - 自动取消订阅
  • 任何 http 订阅 - 这些将发出一次然后完成,因此无需取消订阅
  • 异步管道自动取消订阅

对于您需要手动取消订阅的所有其他内容。有多种方法可以做到这一点,但这里是 RxJs 推荐的方法:

private unsubscribe$ = new Subject()

this.someobservable.pipe(
  takeUntil(this.unsubscribe$)
).subscribe( .... )

ngOnDestroy() {
  this.unsubscribe$.next()
  this.unsubscribe$.complete()
}

推荐阅读