如何退订ngrx/store?
How to unsubscribe from ngrx/store?
我有一个组件可以从订阅商店获取数据。
this.store.select('somedata').subscribe((state: any) => {
this.somedata = state.data;
});
我想在组件不再存在时取消订阅,在我订阅某些可观察对象的其他地方,像这样:
this.service.data.subscribe(
(result: any) => {//data}
);
我在 ngOnOnDestroy 上退订了它,如下所示:
ngOnDestroy(){
this.service.data.unsubscribe();
}
但是如果商店我不能,它给我错误:
Property 'unsubscribe' does not exist on type 'Store<State>'
当你订阅时,你会收到一个订阅对象,你可以调用 unsubscribe()
const subscription = this.store.select('somedata').subscribe((state: any) => {
this.somedata = state.data;
});
// later
subscription.unsubscribe();
或
ngOnInit(){
this.someDataSubscription = this.store.select('somedata').subscribe((state: any) => {
this.somedata = state.data;
});
}
ngOnDestroy(){
this.someDataSubscription.unsubscribe();
}
您不需要首先在您的模板中使用 | async
进行订阅。
您从商店获得的一切都是可见的,让 angular 处理您的订阅。
这里是api
不直接调用subscribe方法也可以取值,像async pipe一样取值
@Component({
template: `
<div>Current Count: {{ counter | async }}</div>
`
})
class MyAppComponent {
counter: Observable<number>;
constructor(private store: Store<AppState>){
this.counter = store.select('counter');
}
}
这里我们使用异步管道来获取值。
异步管道订阅 Observable 或 Promise 和 returns 它发出的最新值。当发出新值时,异步管道标记要检查更改的组件。当组件被销毁时,异步管道会自动取消订阅以避免潜在的内存泄漏。
有一种比得票最高的答案更好的方法,您无需管理一堆订阅,只需管理一个。然后,您可以拥有任意数量的订阅,而无需创建一堆不必要的变量。
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()})
}
我用过的最简洁的方法是使用 ngx-take-until-destroy 库。
您的代码将是这样的:
this.store.select('somedata')
.pipe(untilDestroyed(this))
.subscribe((state: any) => {
this.somedata = state.data;
});
您还需要在 class 中使用 ngOnDestroy()
方法。
此答案基于 and 提供的答案。
无外部库解决方案
避免每个组件与主题及其代码膨胀的一种方法是使用基本组件(使用 Angular 10.0.6 测试):
base.component.ts
import { Subject } from "rxjs";
import { Component } from "@angular/core";
@Component({
selector: "app-base-component",
template: ""
})
export class BaseComponent {
public ngDestroyed$ = new Subject();
public onDestroy(): void {
this.ngDestroyed$.next();
}
}
foo.component.ts
@Component({
selector: "app-foo",
templateUrl: "./foo.component.html",
styleUrls: ["./foo.component.scss"]
})
export class FooComponent extends BaseComponent implements OnInit, OnDestroy {
fooList$: Observable<FooModel[]>;
@ViewChild(DataBindingDirective) dataBinding: DataBindingDirective;
public gridData: any[];
public gridView: any[];
public mySelection: string[] = [];
constructor(private readonly store: Store<AppState>) {
super();
}
ngOnDestroy(): void {
this.onDestroy();
}
ngOnInit(): void {
this.store.dispatch(ApplicationFooItemsRequestedAction());
this.fooList$ = this.store.select(selectAllApplicationFooItems);
this.fooList$.pipe(takeUntil(this.ngDestroyed$)).subscribe(ul => {
// do stuff with items
});
}
}
使用外部库
您可以使用 @ngneat/until-destroy 库来避免自定义代码并支持其他场景(例如在服务中)
@Component({
selector: "app-foo",
templateUrl: "./foo.component.html",
styleUrls: ["./foo.component.scss"]
})
export class FooComponent extends BaseComponent implements OnInit, OnDestroy {
ngOnInit(): void {
this.store.dispatch(ApplicationFooItemsRequestedAction());
this.fooList$ = this.store.select(selectAllApplicationFooItems);
this.fooList$.pipe(takeUntil(untilDestroyed(this))).subscribe(ul => {
// do stuff with items
});
}
}
我有一个组件可以从订阅商店获取数据。
this.store.select('somedata').subscribe((state: any) => {
this.somedata = state.data;
});
我想在组件不再存在时取消订阅,在我订阅某些可观察对象的其他地方,像这样:
this.service.data.subscribe(
(result: any) => {//data}
);
我在 ngOnOnDestroy 上退订了它,如下所示:
ngOnDestroy(){
this.service.data.unsubscribe();
}
但是如果商店我不能,它给我错误:
Property 'unsubscribe' does not exist on type 'Store<State>'
当你订阅时,你会收到一个订阅对象,你可以调用 unsubscribe()
const subscription = this.store.select('somedata').subscribe((state: any) => {
this.somedata = state.data;
});
// later
subscription.unsubscribe();
或
ngOnInit(){
this.someDataSubscription = this.store.select('somedata').subscribe((state: any) => {
this.somedata = state.data;
});
}
ngOnDestroy(){
this.someDataSubscription.unsubscribe();
}
您不需要首先在您的模板中使用 | async
进行订阅。
您从商店获得的一切都是可见的,让 angular 处理您的订阅。
这里是api
不直接调用subscribe方法也可以取值,像async pipe一样取值
@Component({
template: `
<div>Current Count: {{ counter | async }}</div>
`
})
class MyAppComponent {
counter: Observable<number>;
constructor(private store: Store<AppState>){
this.counter = store.select('counter');
}
}
这里我们使用异步管道来获取值。 异步管道订阅 Observable 或 Promise 和 returns 它发出的最新值。当发出新值时,异步管道标记要检查更改的组件。当组件被销毁时,异步管道会自动取消订阅以避免潜在的内存泄漏。
有一种比得票最高的答案更好的方法,您无需管理一堆订阅,只需管理一个。然后,您可以拥有任意数量的订阅,而无需创建一堆不必要的变量。
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()})
}
我用过的最简洁的方法是使用 ngx-take-until-destroy 库。 您的代码将是这样的:
this.store.select('somedata')
.pipe(untilDestroyed(this))
.subscribe((state: any) => {
this.somedata = state.data;
});
您还需要在 class 中使用 ngOnDestroy()
方法。
此答案基于
无外部库解决方案
避免每个组件与主题及其代码膨胀的一种方法是使用基本组件(使用 Angular 10.0.6 测试):
base.component.ts
import { Subject } from "rxjs";
import { Component } from "@angular/core";
@Component({
selector: "app-base-component",
template: ""
})
export class BaseComponent {
public ngDestroyed$ = new Subject();
public onDestroy(): void {
this.ngDestroyed$.next();
}
}
foo.component.ts
@Component({
selector: "app-foo",
templateUrl: "./foo.component.html",
styleUrls: ["./foo.component.scss"]
})
export class FooComponent extends BaseComponent implements OnInit, OnDestroy {
fooList$: Observable<FooModel[]>;
@ViewChild(DataBindingDirective) dataBinding: DataBindingDirective;
public gridData: any[];
public gridView: any[];
public mySelection: string[] = [];
constructor(private readonly store: Store<AppState>) {
super();
}
ngOnDestroy(): void {
this.onDestroy();
}
ngOnInit(): void {
this.store.dispatch(ApplicationFooItemsRequestedAction());
this.fooList$ = this.store.select(selectAllApplicationFooItems);
this.fooList$.pipe(takeUntil(this.ngDestroyed$)).subscribe(ul => {
// do stuff with items
});
}
}
使用外部库
您可以使用 @ngneat/until-destroy 库来避免自定义代码并支持其他场景(例如在服务中)
@Component({
selector: "app-foo",
templateUrl: "./foo.component.html",
styleUrls: ["./foo.component.scss"]
})
export class FooComponent extends BaseComponent implements OnInit, OnDestroy {
ngOnInit(): void {
this.store.dispatch(ApplicationFooItemsRequestedAction());
this.fooList$ = this.store.select(selectAllApplicationFooItems);
this.fooList$.pipe(takeUntil(untilDestroyed(this))).subscribe(ul => {
// do stuff with items
});
}
}