AngularJSカスタムディレクティブのlink関数とcompile関数について、ライフサイクル上の違いを確認し、compile関数を使ったサンプルコードを作成しました。
デモとコードサンプルはこちら。
※目次をクリックすると目次の下部にコンテンツが表示されます。
AngularJSアプリのライフサイクルにおけるcompile関数とlink関数
①HTMLページロード中
・AngularJSのソースコード、アプリのJavaScriptコードをロード。
②HTMLページのロード終了
③document readyイベント発行
・AngularJSが起動し、HTML内のng-appディレクティブを探索。
④すべてのディレクティブを探索
・ng-appディレクティブ内のHTMLの各行を1行ずつ走査し、AngularJSのディレクティブを探索。
・ディレクティブのテンプレートがサーバーやローカルの定義からロードされる。テンプレートはキャッシュされ再利用される。
⑤compile関数を実行
・すべてのディレクティブを認識したところでAngularはcompile関数を実行する。
・compile関数はリストアップされたlink関数をリターンする。
⑥link関数を実行、scopeを結合
・そのディレクティブ用のスコープが生成または取得される。
・リストアップされたlink関数を一つずつ実行する。
・HTMLがscope変数を参照している場合は、scope内の変数の値を取得してブラウザのUIに表示。
・このscopeを保持するコントローラ、サブコントローラがインスタンス化される。
・すべてのディレクティブとバインディングに対するwatcherとlistenerを追加し、各フィールドの変化を検知する。
~この仕組みによってディレクティブによって生成されたテンプレートが正しいスコープに対して評価され、DOMに変換、イベントに反応できる。
~ng-repeatなどそのディレクティブが何度も複製が必要となる場合は、compile関数が複製されたテンプレートを一度だけ実行するのでパフォーマンス上有利になる。
一方、link関数は複製されたインスタンスを逐一実行する。
・AngularJSのソースコード、アプリのJavaScriptコードをロード。
②HTMLページのロード終了
③document readyイベント発行
・AngularJSが起動し、HTML内のng-appディレクティブを探索。
④すべてのディレクティブを探索
・ng-appディレクティブ内のHTMLの各行を1行ずつ走査し、AngularJSのディレクティブを探索。
・ディレクティブのテンプレートがサーバーやローカルの定義からロードされる。テンプレートはキャッシュされ再利用される。
⑤compile関数を実行
・すべてのディレクティブを認識したところでAngularはcompile関数を実行する。
・compile関数はリストアップされたlink関数をリターンする。
⑥link関数を実行、scopeを結合
・そのディレクティブ用のスコープが生成または取得される。
・リストアップされたlink関数を一つずつ実行する。
・HTMLがscope変数を参照している場合は、scope内の変数の値を取得してブラウザのUIに表示。
・このscopeを保持するコントローラ、サブコントローラがインスタンス化される。
・すべてのディレクティブとバインディングに対するwatcherとlistenerを追加し、各フィールドの変化を検知する。
~この仕組みによってディレクティブによって生成されたテンプレートが正しいスコープに対して評価され、DOMに変換、イベントに反応できる。
~ng-repeatなどそのディレクティブが何度も複製が必要となる場合は、compile関数が複製されたテンプレートを一度だけ実行するのでパフォーマンス上有利になる。
一方、link関数は複製されたインスタンスを逐一実行する。
カスタムディレクティブのcompile関数
1)構文
compile: function(tElement, attrs) { … }
tElement:そのディレクティブが適用される要素
tAttrs:その要素で定義される正規化された属性のリスト
2)compile関数の概要
・compile関数は、link関数が実行される前にDOMの変換を行う。
・compile関数はscopeにアクセスはせず、link関数を返さなければならない。
・compile関数が無い場合は、通常通りlink関数を定義出来る。
・多くのディレクティブは、link関数内でのみ作用するイベントリスナー、watchersの登録、DOMの更新などを行うのでlink関数のみで動作する。
・クローンを必要としたり、DOM要素を何度も繰り返し使用するng-repeatのようなディレクティブは、link関数を実行する前にcompile関数を使用する。
compile: function(tElement, attrs) { … }
tElement:そのディレクティブが適用される要素
tAttrs:その要素で定義される正規化された属性のリスト
2)compile関数の概要
・compile関数は、link関数が実行される前にDOMの変換を行う。
・compile関数はscopeにアクセスはせず、link関数を返さなければならない。
・compile関数が無い場合は、通常通りlink関数を定義出来る。
・多くのディレクティブは、link関数内でのみ作用するイベントリスナー、watchersの登録、DOMの更新などを行うのでlink関数のみで動作する。
・クローンを必要としたり、DOM要素を何度も繰り返し使用するng-repeatのようなディレクティブは、link関数を実行する前にcompile関数を使用する。
サンプルコード
AngularJSの特徴、仕組み
ビルトインディレクティブ
- ビルトインのディレクティブの概要
- データバインディングのディレクティブの概要
- ng-repeatを使ってリスト、テーブル、フィルター
- ng-includeを使って別のHTMLファイルを埋め込み
- ng-switchを使って内部にあるHTMLテンプレートの表示を切り替え
- ng-if、ng-show、ng-hideを使って表示、非表示を切り替え
- ng-class、ng-styleを使ってCSSを設定
- イベント処理
- 有効、無効を切替えるディレクティブ
- フォームの入力チェックを行い、動的にCSS追加
- ng-optionsを使ってSelectメニューを作成
- ng-repeatを使ってラジオボタンを作成
- ビルトインのフィルターの使用方法
- ビルトインのフィルターで関数を使用
- カスタムフィルターの使用方法
- Bootstrap3を使ってページング
- スクリプト内でフィルターを使用、既存のフィルターを拡張
サービス
- サービスの概要とfactory、service、providerの使い分け
- $qサービスでpromise/deferredパターン
- $httpサービスの概要、サーバーからJSONデータ取得
- $httpサービスのPOSTでデータ送信
- $qサービスを使ってhttpリクエストを複数実行
- $httpサービスのinterceptorの使用方法
- AngularJSのwithCredentialsの設定、CORS
- $timeoutサービスと$intervalサービス
- $resourceサービスを使ってREST
- $locationサービスを使ってURLを操作
- $routeサービスと$resourceサービスを使ったサンプルを作成
- routeChangeSuccessを使ってflashメッセージ表示
- JavaScript、CSSを含むHTMLデータをバインドして表示
カスタムディレクティブ
AngularJSの特徴、仕組み
ビルトインディレクティブ
- ビルトインのディレクティブの概要
- データバインディングのディレクティブの概要
- ng-repeatを使ってリスト、テーブル、フィルター
- ng-includeを使って別のHTMLファイルを埋め込み
- ng-switchで内部にあるHTMLテンプレートの表示を切り替え
- ng-if、ng-show、ng-hideを使って表示、非表示を切り替え
- ng-class、ng-styleを使ってCSSを設定
- イベント処理
- 有効、無効を切替えるディレクティブ
- フォームの入力チェックを行い、動的にCSS追加
- ng-optionsを使ってSelectメニューを作成
- ng-repeatを使ってラジオボタンを作成
- ビルトインのフィルターの使用方法
- ビルトインのフィルターで関数を使用
- カスタムフィルターの使用方法
- Bootstrap3を使ってページング
- スクリプト内でフィルターを使用、既存のフィルターを拡張
サービス
- サービスの概要とfactory、service、providerの使い分け
- $qサービスでpromise/deferredパターン
- $httpサービスの概要、サーバーからJSONデータ取得
- $httpサービスのPOSTでデータ送信
- $qサービスを使ってhttpリクエストを複数実行
- $httpサービスのinterceptorの使用方法
- AngularJSのwithCredentialsの設定、CORS
- $timeoutサービスと$intervalサービス
- $resourceサービスを使ってREST
- $locationサービスを使ってURLを操作
- $routeサービスと$resourceサービスを使ったサンプルを作成
- routeChangeSuccessを使ってflashメッセージ表示
- JavaScript、CSSを含むHTMLデータをバインドして表示
カスタムディレクティブ