在一个有角度的应用程序中,我们使用 ngOnDestroy()生命周期钩子作为组件/指令,并使用这个钩子来取消订阅可观察到的内容。
ngOnDestroy()
我想清除/销毁在 @injectable()服务中创建的可观察到的。 我看到一些帖子说 ngOnDestroy()也可以在服务中使用。
@injectable()
但是,这是一个好的实践和唯一的方法吗? 它什么时候会被调用? 有人能澄清一下吗。
在服务中创建一个变量
subscriptions: Subscriptions[]=[];
将每个订阅按如下方式推送到数组
this.subscriptions.push(...)
编写一个 dispose()方法
dispose()
dispose(){ this.subscriptions.forEach(subscription =>subscription.unsubscribe())
在 ngOnDestroy 期间从组件调用此方法
ngOnDestroy(){ this.service.dispose(); }
只是要澄清-你不需要销毁 Observables,但只有订阅了他们。
Observables
似乎其他人已经指出,您现在也可以将 ngOnDestroy与服务一起使用。链接: https://angular.io/api/core/OnDestroy
ngOnDestroy
OnDestroy 生命周期钩子在提供程序中可用。 根据文件:
当指令、管道或服务被破坏时调用的生命周期钩子。
这是 例子:
@Injectable() class Service implements OnDestroy { ngOnDestroy() { console.log('Service destroy') } } @Component({ selector: 'foo', template: `foo`, providers: [Service] }) export class Foo implements OnDestroy { constructor(service: Service) {} ngOnDestroy() { console.log('foo destroy') } } @Component({ selector: 'my-app', template: `<foo *ngIf="isFoo"></foo>`, }) export class App { isFoo = true; constructor() { setTimeout(() => { this.isFoo = false; }, 1000) } }
请注意,在上面的代码中,Service是一个属于 Foo组件的实例,因此当 Foo被销毁时,它可以被销毁。
Service
Foo
对于属于 root 注入器的提供程序,这将在应用程序销毁时发生,这有助于避免多个引导程序(即在测试中)的内存泄漏。
当来自父注入器的提供者在子组件中订阅时,它不会在组件销毁时被销毁,这是组件在组件 ngOnDestroy中取消订阅的责任(另一个答案解释)。
我更喜欢这种由可管操作符启用的 takeUntil(onDestroy$)模式。我喜欢这种模式更简洁、更干净,它清楚地表达了在执行 OnDestroy生命周期钩子时终止订阅的意图。
takeUntil(onDestroy$)
OnDestroy
这种模式适用于服务以及订阅注入的可观察对象的组件。下面的框架代码将提供足够的细节,以便将模式集成到您自己的服务中。假设你正在导入一个名为 InjectedService的服务..。
InjectedService
import { InjectedService } from 'where/it/lives'; import { Injectable, OnDestroy } from '@angular/core'; import { Observable } from 'rxjs/Rx'; import { takeUntil } from 'rxjs/operators'; import { Subject } from 'rxjs/Subject'; @Injectable() export class MyService implements OnDestroy { private onDestroy$ = new Subject<boolean>(); constructor( private injectedService: InjectedService ) { // Subscribe to service, and automatically unsubscribe upon `ngOnDestroy` this.injectedService.observableThing().pipe( takeUntil(this.onDestroy$) ).subscribe(latestTask => { if (latestTask) { this.initializeDraftAllocations(); } }); } ngOnDestroy() { this.onDestroy$.next(true); this.onDestroy$.complete(); }
关于何时/如何取消订阅的话题在这里被广泛讨论: Angular/RxJs 何时退订
为了使我的应用程序尽可能模块化,我经常使用提供者令牌来为组件提供服务。看起来这些不得到他们的 ngOnDestroy方法调用:-(
例如。
export const PAYMENTPANEL_SERVICE = new InjectionToken<PaymentPanelService>('PAYMENTPANEL_SERVICE');
使用组件中的提供程序部分:
{ provide: PAYMENTPANEL_SERVICE, useExisting: ShopPaymentPanelService }
在释放组件时,我的 ShopPaymentPanelService没有调用它的 ngOnDestroy方法。我也是吃了苦头才知道的!
ShopPaymentPanelService
解决方案是结合 useExisting提供服务。
useExisting
[ ShopPaymentPanelService, { provide: PAYMENTPANEL_SERVICE, useExisting: ShopPaymentPanelService } ]
当我这样做的时候,ngOnDispose被调用了。
ngOnDispose
不确定这是不是一个错误,但是非常出乎意料。
在服务中创建一个变量:
private subscriptions$ = new Subscription();
将每个订阅添加到构造函数(或 ngOnInit 生命周期挂钩)中的可观察项
ngOnInit() { this.subscriptions.add(...) this.subscriptions.add(...) }
销毁时从组件调用此方法以取消对所有订阅和子订阅的订阅。
ngOnDestroy(){ this.subsriptions$.unsubscribe(); }
我建议使用. tube (take (1)) . ordering ()。