スコープのプロパティ値の変更
これまではリスト2のように、スコープのプロパティに値を設定するだけで問題なくデータバインディングは機能し、HTMLテンプレートに値が反映されました。
$scope.name = "foo";
しかし、実はこれだけでは値が反映されない場合があります。例えば、リスト3のようなコードでは、message.showの値を変えて非表示にするようにしても、いつになっても非表示にはなりません。これは、AngularJSが値の変更を検知できないためにおきる現象です。
setTimeout(function(){
$scope.message.show = false;
},3000);
// <div ng-show="message.show"> HTMLテンプレート側の記述
このような現象を回避するには、既にAngularJSで用意されているサービスを利用すれば問題はなく、setTimeoutを扱うための$timeout サービスが存在します。
リスト4は$timeoutサービスを用いたサンプルコードの抜粋です。
最初に(1)ではpageControllerで表示するメッセージを定義しています。ここで定義されたメッセージは、テンプレート側でリスト5(index.html抜粋)のように表示されます。
リスト4で実装したい動作は、データの登録後にメッセージを表示し、その3秒後に非表示にするというものです。そのために(2)ではまず、表示するデータを設定します。このままでは表示されたままになってしまうので、(3)で$timeoutサービスを使って3秒(3000ミリ秒)後に非表示にしています。
module.controller('pageController',function($scope,$timeout){
// : 省略
// (1) ワーニング等のメッセージ表示
$scope.message = {
type : 'alert-info',
text : '',
show : false
};
$scope.showMessage = function(msg){
$scope.message = msg; // (2) テンプレート側との同期
$timeout(function(){ // (3) $timeoutの利用
$scope.message.show = false;
},3000);
};
});
module.controller('addController',function($scope){
$scope.addItem = function() {
// : 省略
$scope.$parent.showMessage({ // (4) showMessageの表示
type: 'alert-info',
text: '追加しました',
show: true
});
// : 省略
};
});
<div class="container" ng-show="show.list">
<div ng-show="message.show">
<div class="alert" role="alert" ng-class="message.type">
<span>{{message.text}}</span>
</div>
</div>
</div>
$timeout のほかにも、AngularJSで用意されているサービス は数多くあります。
自分の利用したい機能がサービスに用意されていない場合や、ほかのライブラリを利用したい場合には、$scopeオブジェクトの$applyメソッドを利用することでプロパティの変更を通知することができます。
リスト6は、setTimeout関数を用いてプロパティ変更をしている例です。できるだけAngularJSで用意されているサービスを利用した方がよいのですが、どうしても既存のコードなどを組み合わせてプログラムを記述する場合などには、ここで紹介した$applyメソッドを使う必要があるということを覚えておくとよいでしょう。
setTimeout(function(){
$scope.$apply(function(){ // (1) $scope.$applyを利用する
$scope.message.show = false;
});
},3000);
