订阅 ngrx 商店多次触发

cup*_*_of 4 observable typescript ngrx angular ngrx-store

我有一个设置了 ngrx 商店的应用程序。我订阅它是为了在单击按钮时触发的函数中从商店获取数据,我正在获取我想要的数据,但每次触发该函数时,它似乎都会返回数据的多个副本,当我再次点燃它,它会呈指数级增长。

因此,在我的选择器中component.ts,我的选择器连接到商店以获取我的数据:

this.data$ = this.store.pipe(select(selectors.dataSelector));

然后我的函数在点击时触发(在我的html中)

  onClick() {
     this.data$.subscribe(x =>
       console.log(x)
     );
   }
Run Code Online (Sandbox Code Playgroud)

因此,经过一次迭代后:

在此输入图像描述

两点之后:

在此输入图像描述

三后:

在此输入图像描述

等等。为什么会发生这种情况,或者是否有不同的方式从存储中获取数据component.ts?我需要它只返回一次数据,否则性能会受到很大影响。

Ser*_*len 6

data$因为您每次点击都会订阅。如果您想这样做,onClick可以在您取消订阅后console.log(x)或使用rxjs take()

  onClick() {
     this.data$.pipe(take(1)).subscribe(x =>
       console.log(x)
     );
   }
Run Code Online (Sandbox Code Playgroud)

来自文档:

为什么要使用take

当您只对第一组发射次数感兴趣时,您需要使用 take。也许您想查看用户第一次进入页面时首先单击的内容,您可能希望订阅单击事件并仅获取第一次发射。

https://www.learnrxjs.io/operators/filtering/take.html

但我的建议是您在其他地方订阅商店,例如在组件构造函数中:

constructor(store) {
   store.pipe(select(selectors.dataSelector)).subscribe(x => {
       this.componentX = x;
   });
}
Run Code Online (Sandbox Code Playgroud)

然后只需单击即可看到如下数据:

onClick() {
   console.log(this.componentX);
}
Run Code Online (Sandbox Code Playgroud)

这样,您只需在组件初始化时订阅一次。

关于订阅以及如何防止内存泄漏的另一件事是,当组件被销毁时,始终取消订阅。

https://brianflove.com/2016/12/11/anguar-2-unsubscribe-observables/