如何取消订阅ngrx/store?

Mic*_*ips 11 angular ngrx-store

我有一个组件从订阅商店获取其数据.

this.store.select('somedata').subscribe((state: any) => {
  this.somedata = state.data;
});
Run Code Online (Sandbox Code Playgroud)

我想在组件不再使用时取消订阅此订阅,在我订阅某些observable的其他地方,如下所示:

this.service.data.subscribe(
   (result: any) => {//data}
);
Run Code Online (Sandbox Code Playgroud)

我在ngOnOnDestroy上取消订阅,如下所示:

ngOnDestroy(){
   this.service.data.unsubscribe();
}
Run Code Online (Sandbox Code Playgroud)

但是如果商店我不能,它会给我错误:

Property 'unsubscribe' does not exist on type 'Store<State>'
Run Code Online (Sandbox Code Playgroud)

G.V*_*lli 20

订阅时,您将收到订阅对象,您可以调用unsubscribe()

const subscription = this.store.select('somedata').subscribe((state: any) => {
  this.somedata = state.data;
});
// later
subscription.unsubscribe();
Run Code Online (Sandbox Code Playgroud)

要么

ngOnInit(){
 this.someDataSubscription = this.store.select('somedata').subscribe((state: any) => {
  this.somedata = state.data;
 });
}

ngOnDestroy(){
  this.someDataSubscription.unsubscribe();
}
Run Code Online (Sandbox Code Playgroud)

  • 对于许多订阅,有一种更简单、更简洁的方法来做到这一点。用`takeUntil(this.$ngDestroyed)`查看答案 (3认同)

Fla*_*ape 14

有一种比最高投票的答案更好的方式,你不需要管理一堆订阅,只有一种.然后,您可以根据需要拥有尽可能多的订阅,而无需创建一堆不必要的变量.

  public ngDestroyed$ = new Subject();

  public ngOnDestroy() {
    this.ngDestroyed$.next();
  }

  public ngOnInit() {
    this.myWhateverObs$
        .pipe(takeUntil(this.ngDestroyed$))
        .subscribe((val)=> { this.whatever()});
    this.myWhateverNPlusOne$
        .pipe(takeUntil(this.ngDestroyed$))
        .subscribe((val)=> { this.whatever()})
  }
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你的解决方案.我在应用程序中有多个订阅.使用上述方法是一场噩梦. (3认同)
  • 必须在 `ngDestroyed$.next()` 之后调用 `ngDestroyed$.complete()`,否则会泄露主题。它可能是一个小对象,但它会提醒活动... 关于顺序:“takeUntil”始终是最后一个,期望“shareReply”、“multicast”和类似的多播运算符。 (3认同)

Aks*_*arg 5

您可以在不直接调用subscribe方法的情况下获取值,通过异步管道获取值

@Component({
    template: `
        <div>Current Count: {{ counter | async }}</div>
    `
})
class MyAppComponent {
    counter: Observable<number>;

    constructor(private store: Store<AppState>){
        this.counter = store.select('counter');
    }
}
Run Code Online (Sandbox Code Playgroud)

这里我们使用异步管道来获取价值.异步管道订阅Observable或Promise并返回它发出的最新值.发出新值时,异步管道会标记要检查更改的组件.当组件被销毁时,异步管道会自动取消订阅以避免潜在的内存泄漏.


小智 5

我使用过的最简洁的方法是使用ngx-take-until-destroy库。你的代码将是这样的:

this.store.select('somedata')
    .pipe(untilDestroyed(this))
    .subscribe((state: any) => {
        this.somedata = state.data;
    });
Run Code Online (Sandbox Code Playgroud)

ngOnDestroy()你的班级还需要有方法。