はじめに
Angular 2はGoogleとオープンソースコミュニティで開発されているJavaScriptフレームワークで、従来のAngularJS(AngularJS 1)の次期バージョンです。
Angular 2で作成したWebページを構成するコンポーネントは、表示時に生成され、画面の入力や表示などで状態が変更されて、非表示時に破棄されるといったライフサイクルが定義されています。開発者は、ライフサイクルの変化ごとに呼び出されるメソッド(ライフサイクルフック)を実装して、ライフサイクルに対応した処理を実行できます。
本記事では、Angular 2のライフサイクルとライフサイクルフックについて、サンプルを使って説明していきます。
対象読者
- Angular 2をより深く使いこなしていきたい方
- 最新のフレームワークを活用したい方
- Angular 2が裏でどう動いているか気になる方
必要な環境
Angular 2はJavaScriptのフレームワークですが、公式WebサイトのドキュメントやサンプルはTypeScript向けが先行して整備される場合が多く、本連載でもTypeScriptでコードを記述していきます。また、サンプルの実行にはNode.jsが必要になります。
今回は以下の環境で動作を確認しています。
-
Windows 10 64bit版
- Angular 2 2.4.0
- Node.js v6.9.5 64bit版
- Microsoft Edge 38.14393.0.0
公式サイトのガイドでは、GitHubからダウンロードできるプロジェクトテンプレートで実装環境を作るよう案内されています。テンプレートを展開したフォルダで、Node.jsのコマンド「npm install」を実行して依存ライブラリをダウンロード後、「npm start」コマンドを実行すると、WebブラウザでWebページを表示できます。本記事のサンプルもこのテンプレートをもとに実装しています。
Angular 2のライフサイクル
Angular 2のコンポーネントは、図1のようなライフサイクルで生成→変更→消滅します。
ライフサイクルに対応するメソッド(ライフサイクルフック)が、表1のように定義されています。ライフサイクルフックは特定のタイミングや、別のライフサイクルフックの実行後に実行されます。
No. | メソッド名 | 実行タイミング |
---|---|---|
1 | ngOnChanges | コンポーネントの入力プロパティ変更時 |
2 | ngOnInit | 生成時、No.1の実行後 |
3 | ngDoCheck | 変更を検知したとき、No.1または2の実行後 |
4 | ngAfterContentInit | 外部コンテンツ初期化時、No.3の実行後(1回だけ) |
5 | ngAfterContentChecked | 外部コンテンツ変更時、No.3または4の実行後 |
6 | ngAfterViewInit | ビュー初期化時、No.5の実行後(1回だけ) |
7 | ngAfterViewChecked | ビュー変更時、No.5または6の実行後 |
8 | ngOnDestroy | 破棄時 |
[用語説明]入力プロパティ、外部コンテンツ、ビュー
No.1の「入力プロパティ」は、リスト1の[input1]のように、コンポーネントタグの属性で指定するプロパティです。コンポーネントでは、@Inputデコレーターで入力プロパティを参照できます。
<comp [input1]="input1Value"></comp>
No.4、5の「外部コンテンツ」は、リスト2のpタグ要素のように、コンポーネントタグで囲まれた内容です。コンポーネントでは、<ng-content>タグで外部コンテンツを参照できます。
<comp> <p>外部コンテンツ</p> </comp>
No.6、7の「ビュー」は、@Componentデコレーターのtemplate属性に指定したHTMLテンプレートで定義される、コンポーネントの画面表示です。
ライフサイクル遷移をログ出力する図2のサンプル(001-all-hooks)で、実際にライフサイクルの様子を見てみます。
図2のサンプルを実行すると、コンストラクターの実行後に表1のライフサイクルフックが順に実行され、図3のようにデバッグログ出力されます。
図3では、まず外部プロパティが設定されることでngOnChangesが実行され、後続してngOnInit~ngAfterViewCheckedが実行されます(1)。次に、Angular 2が画面の変更を検知する処理を行うため、ngDoCheckと、後続するngAfterContentChecked、ngAfterViewCheckedが実行されます(2)。最後に、画面の「コンポーネントを破棄」ボタンを押すと、コンポーネントが破棄(画面から削除)されて、ngOnDestroyが実行されます(3)。
ライフサイクルフックを実行するコンポーネントの実装はリスト3です。
import { Component, Input, OnChanges, OnInit, DoCheck, AfterContentInit, AfterContentChecked, AfterViewInit, AfterViewChecked, OnDestroy } from "@angular/core"; // インターフェースを参照...(1) (略) export class LifeCycleComponent implements OnChanges, OnInit, DoCheck, AfterContentInit, AfterContentChecked, AfterViewInit, AfterViewChecked, OnDestroy // インターフェースを設定...(2) { // コンストラクター ...(3) constructor() { console.debug("constructor"); } // ライフサイクルフック ...(4) ngOnChanges() { console.debug("ngOnChanges"); } (以下、各ライフサイクルフックのメソッド) }
(1)で、ライフサイクルフックに対応するTypeScriptのインターフェースを参照して、(2)で設定します。(3)はコンストラクター、(4)以下が各ライフサイクルフックです。サンプルでは、ライフサイクルフック実行時に、名前をデバッグログに出力します。