AngularJSのDirectiveは、HTMLでどのようにDOMを組み立てるか命令するものです。Directiveは例えば「ng-app」のようにHTMLのカスタム属性を使って記述していきます。
ここでは、「ng-model」 ディレクティブを使った簡単な例で説明します。これはスコープの中で「ng-model」属性で指定した値と同じプロパティを探します。そうすることでスコープにあるプロパティの値とDOMをバインドすることができます。さらにこのバインドは双方向バインドであり、vewで変更した値はcontrollerでも反映し、controllerで変更した値はvewでも反映される優れものです。
次のサンプルはAngularJSを使った入力項目をリアルタイムに表示するサンプルです。
デモ
入力した値がリアルタイムでpタグ内で反映されます。
HTMLコード
1 2 3 4 5 6 7 8 | < div ng-controller = "mainController" > < div > < label >名前を入力してください</ label > < input type = "text" ng-model = "name" > </ div > < hr > < p >お名前は…{{name}}</ p > </ div > |
AngularJSコード
1 2 3 4 | var myApp = angular.module( 'myApp' , []); myApp.controller( 'mainController' ,[ '$scope' , function ($scope) { $scope.name = '' ; }]); |
AngularJSコードではまず、「myApp」というモジュールを作成しています。
続いて、mainControllerを作成して$scopeオブジェクトのnameプロパティに空の値を代入しています。あとはHTML側のinput要素に「ng-model=”name”」というディレクティブを指定することで$scopを通してcontrollerとバインドしています。
これで入力値をリアルタイムに表示することができています。
リアルタイムに変化する仕組みにはAngularJS特有のイベント処理があります。それはAngularJS内部で$watchを使ってイベント前後の変化を認識しています。
$watchは変化があった場合、その値、や関数に関わる全ての変化前、変化後を管理しています。つまりこれがバインドの仕組みを支えている訳です。
$watch による変更の感知は、定期的に実施されるのではなく、$digestサイクルの中DOMイベントが生じた時などに処理が実行されています。
ng-bindに付いて
また、実用面ではHTML部分の「お名前は…{{name}}」ではAngularJSの処理が終わるまでの一瞬チラつきがでます。これを防ぐにはインターポレーションを使わずに次の記述を使用します。
1 | < p ng-bind = "name" ></ p > |
つまり「お名前は…{{name}}」と同等の結果になります。
1 2 3 | < p >お名前は…{{name}}</ p > <-- 上と下の記述は同等の結果になる--> < p ng-bind = "name" ></ p > |
ng-bindは属性として使われて要素自体は空の状態です。そのためインターポレーションの{{}}が一瞬見えるようなことはないのです。