1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

AngularのサービスをngOnDestroyで解放する

Posted at

先日の ng-japan OnAir を視聴していて知ったこと。サービスに ngOnDestroy が書けるとのこと。知らなかった…!

この記事のコードの前提条件

  • Angular 15

サービス

ngOnDestroy を書くだけ。
service.png

コンポーネントとサービスのライフタイムが一致する場合

コンポーネントメタデータの providers でサービスを指定する。このようにするとエレメントインジェクターでサービスのインスタンスが生成され、コンポーネントとサービスのライフタイムが一致する。

コンポーネント破棄のタイミングでサービス内の ngOnDestroy が呼ばれる。
foo.png

コンポーネントよりサービスのほうが長く生存する場合

コンポーネントメタデータの providers でサービスを指定しない。このようにするとルートインジェクターでサービスのインスタンスが生成され、コンポーネントよりサービスほうが長く生存する。(モジュールインジェクターを使っても同じ)

コンポーネント破棄のタイミングでサービス内の ngOnDestroy は呼ばれない。
bar.png

検証してみる

ルーティングを宣言して、ページ移動によりコンポーネントが生成・破棄されるようにした。
サービスの ngOnDestroy が呼ばれたかコンソール出力で判定する。
app.png

module.png

home → foo → home とリンクを辿る。 FooComponent(エレメントでサービス注入)が破棄されるタイミングでサービスの ngOnDestroy が呼ばれる。
home-foo-home.png

home → bar → home とリンクを辿る。BarComponent(ルートでサービス注入)が破棄されるタイミングでサービスはまだ生存しているため ngOnDestroy は呼ばれない。
home-bar-home.png

検証したコードは以下のURLで公開。
https://codesandbox.io/s/happy-heisenberg-n6018

ユースケース

サービス内で Observable を購読したり、setInterval で定期処理を実行しているようなケースで役立つ。

コンポーネントの ngOnDestroy で呼び出していた終了処理がサービスの「自分自身が破棄されたタイミング」という関心事になり、終了処理の呼び忘れなどが防げる。利用者であるコンポーネントはインジェクターを変えることで終了処理のタイミングを指示できるようになる。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?