你什么时候取消订阅角度分量中的可观察量?

问题描述 投票:0回答:1

当我们将 ngrx 与 Angular 一起使用时,假设我从变量中的组件中的选择器中获取数据,在 ngOnDestroy 中我应该使用 unsubscribe 方法取消订阅还是 ngrx select 方法会执行此操作?

data$ : Observable<any>;

ngOnInit(){

  data$ = this.store.select(selectData);

}

ngOnDestroy(){}

angular rxjs ngrx ngrx-store
1个回答
0
投票

取消订阅可观察对象的方法有很多种!据我所知,

ngrx
无法为您做到这一点,因为这是由开发人员决定的。

关于订阅可观察对象以在模板中显示一些数据的主题:

稳定的方式

推荐自动订阅:使用
AsyncPipe

订阅 observables 的推荐方法是 如果可以的话,使用模板中的

AsyncPipe
。这样,当组件被销毁时,Angular 将负责取消订阅。尝试尽可能多地使用它作为默认值。

除非您使用信号,否则信号会在没有异步管道的情况下自动处理🪄

Angular 管理可观察订阅的好处远不止于此。如果过渡到无区域应用程序或转向

OnPush
更改检测策略,这将会有所帮助。由于当新值通过可观察值时,Angular 会将视图标记为脏视图,因此将有助于变更检测管理。

例如,如果您想转储数据(假设它是 JSON 并希望全部转储),模板将如下所示

<pre>{{ data$ | async | json }}</pre>

手动订阅和取消订阅

如果您无法使用

AsyncPipe
,那么当组件在
ngOnDestroy
生命周期钩子中被销毁时,您可以按照您的预期手动订阅和取消订阅。

export class FooComponent implements OnDestroy {
  data: any
  dataSubscription: Subscription;

  ngOnInit(){
    this.dataSubscription = this.store.select(selectData)
      .subscribe((data) => this.data = data)
  }

  ngOnDestroy(){
    this.dataSubscription.unsubscribe()
  }
}

然后在您的模板中:

<pre>{{ data | json }}</pre>

手动订阅:通过
takeUntil
操作员

如果您开始拥有多个订阅,那么拥有所有这些订阅可能会很混乱。您可以将它们存储在

subscriptions
数组中,然后将它们全部存储在
unsubscribe
中。或者您也可以使用
ngOnDestroy 和一个额外的 observable 来全部取消订阅
:
takeUntil

然后您可以照常在模板中使用 
export class FooComponent { unsubscribeSignal: Subject<void> = new Subject(); data: any moarData: any ngOnInit() { this.data = this.store.select(selectData) .pipe(takeUntil(this.unsubscribeSignal)) .subscribe((data) => this.data = data); this.moarData$ = this.store.select(selectMoarData) .pipe(takeUntil(this.unsubscribeSignal)) .subscribe((moarData) => this.moarData = moarData); } ngOnDestroy(){ this.unsubscribeSignal.next(); this.unsubscribeSignal.unsubscribe(); } }

data
(如前面的示例所示)

有一些库可以通过为您创建额外的可观察值来帮助您实现此策略。但还没有使用过它们,而且它们似乎已经过时了,所以不能推荐任何

不稳定、前沿的方式(在开发者预览中)

请注意,以下 API 处于开发者预览版,因此尚不稳定,将来可能会发生变化

有信号

如果您想开始使用信号,您还可以使用

moarData API

 将您的可观察量转换为信号,该 API
内置于 toSignal
 包中。这样,当组件被破坏时,信号就会被破坏。

具体方法如下:

@angular/core
然后,在您的模板中(再次使用 JSON 管道转储整个内容):

export class FooComponent { data: Signal<any>; ngOnInit(){ data = toSignal(this.store.select(selectData)) } }
使用 

<pre>{{ data() | json }}</pre>
 API

还有一个新的

takeUntilDestroyed

 API
destroy 可以帮助您在组件被销毁时自动取消订阅一个或多个可观察对象。与上面描述的取消订阅多个可观察的方式类似。但好处是不必自己维护额外的可观察量来向其他可观察量表明该组件正在被破坏。

但是,该 API 只能在注入上下文中使用(例如,在将可观察量定义为类字段或在构造函数中时调用它)。

takeUntilDestroyed
如果您将其传递给 

export class FooComponent { data: any // 👇 Important to be in an injection context // Otherwise, won't work constructor() { this.store.select(selectData).pipe(takeUntilDestroyed()) .subscribe((data) => this.data = data) } }

,您也可以在注入上下文之外使用它。查看 
这篇博文 进一步解释这个新 API。

© www.soinside.com 2019 - 2024. All rights reserved.