回答:
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
と破棄される可能性があることに注意してください。
ルートインジェクターに属するプロバイダーの場合、これはアプリケーションの破棄時に発生します。これは、複数のブートストラップ、つまりテストでのメモリリークを回避するのに役立ちます。
親インジェクターからのプロバイダーが子コンポーネントでサブスクライブされている場合、それはコンポーネント破棄で破棄されません。これはコンポーネントでサブスクライブ解除するコンポーネントの責任ですngOnDestroy
(別の回答で説明されています)。
implements OnDestroy
何も影響しませんが、完全にするために追加できます。のように、モジュールが破壊されたときに呼び出されますappModule.destroy()
。これは、複数のアプリの初期化に役立つ場合があります。
サービスに変数を作成します
subscriptions: Subscriptions[]=[];
各サブスクライブを配列にプッシュします
this.subscriptions.push(...)
dispose()
メソッドを書く
dispose(){
this.subscriptions.forEach(subscription =>subscription.unsubscribe())
ngOnDestroy中にコンポーネントからこのメソッドを呼び出します
ngOnDestroy(){
this.service.dispose();
}
@injectables
このtakeUntil(onDestroy$)
パターンは、pipableオペレーターによって有効化されることを好みます。このパターンはより簡潔でクリーンであり、実行時にサブスクリプションを強制終了する意図を明確に伝えているのが好きですOnDestroy
ライフサイクルフックの。
このパターンは、サービスと、注入されたオブザーバブルにサブスクライブするコンポーネントで機能します。以下のスケルトンコードは、パターンを独自のサービスに統合するのに十分な詳細を提供します。というサービスをインポートしているとしましょう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 `Subscription`から購読を解除する必要があるとき
明確にするために-破棄する必要はなくObservables
、それらに対して行われたサブスクリプションのみを破棄します。
他の人もあなたがngOnDestroy
サービスでも使用できるようになったと指摘しているようです。リンク:https : //angular.io/api/core/OnDestroy
アプリケーションを可能な限りモジュール化しようとする場合、プロバイダートークンを使用してコンポーネントにサービスを提供することがよくあります。これらはngOnDestroy
呼び出されたメソッドを取得していないようです:-(
例えば。
export const PAYMENTPANEL_SERVICE = new InjectionToken<PaymentPanelService>('PAYMENTPANEL_SERVICE');
コンポーネントにプロバイダーセクションがある場合:
{
provide: PAYMENTPANEL_SERVICE,
useExisting: ShopPaymentPanelService
}
私ShopPaymentPanelService
はngOnDestroy
、コンポーネントが破棄されるときに呼び出されるメソッドを持っていません。私はこれを難しい方法で見つけました!
回避策は、と組み合わせてサービスを提供することuseExisting
です。
[
ShopPaymentPanelService,
{
provide: PAYMENTPANEL_SERVICE,
useExisting: ShopPaymentPanelService
}
]
私がこれをしたとき、それはngOnDispose
期待通りに呼ばれました。
これがバグかどうかはわかりませんが、非常に予想外です。
class Service implements OnDestroy
?そして、サービスがモジュールレベルで提供されている場合、これが呼び出されたときにどう思いますか