AngularJSのDirectiveは、HTMLでどのようにDOMを組み立てるか命令するものです。Directiveは例えば「ng-app」のようにHTMLのカスタム属性を使って記述していきます。
ここでは、「ng-model」 ディレクティブを使った簡単な例で説明します。これはスコープの中で「ng-model」属性で指定した値と同じプロパティを探します。そうすることでスコープにあるプロパティの値とDOMをバインドすることができます。さらにこのバインドは双方向バインドであり、vewで変更した値はcontrollerでも反映し、controllerで変更した値はvewでも反映される優れものです。
次のサンプルはAngularJSを使った入力項目をリアルタイムに表示するサンプルです。
デモ
入力した値がリアルタイムでpタグ内で反映されます。
HTMLコード
<div ng-controller="mainController"> <div> <label>名前を入力してください</label> <input type="text" ng-model="name"> </div> <hr> <p>お名前は…{{name}}</p> </div>
AngularJSコード
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の処理が終わるまでの一瞬チラつきがでます。これを防ぐにはインターポレーションを使わずに次の記述を使用します。
<p ng-bind="name"></p>
つまり「お名前は…{{name}}」と同等の結果になります。
<p>お名前は…{{name}}</p> <-- 上と下の記述は同等の結果になる--> <p ng-bind="name"></p>
ng-bindは属性として使われて要素自体は空の状態です。そのためインターポレーションの{{}}が一瞬見えるようなことはないのです。