AngularJS 変更監視 Scope#$watchの補足とScope#$apply
$watchについて以前書きましたがその補足と$applyについてです。
blog.howdylikes.jp
文字列の代わりにfunctionで変更監視対象を直接指定することが可能
と記載しましたがその補足です。
以下のscript内ではwindowオブジェクトのglobal
を監視対象としています(普通は書きませんが動作確認のためです)
this.dummy()
が呼ばれた場合もScopeの監視処理自体は走ります。
※ng-clickで$digestサイクルが実行されるかららしい
changeValue()
が呼ばれた場合、globalを書き換えても$digestサイクルが実行されないのでScopeの監視処理は走りません。
callApply()
内で$scopeを取得して$apply()を実行していますが、これは内部的に$digestサイクルを実行しているということらしい。
つまりchangeValue()
の後にthis.dummy()
やcallApply()
など$digestサイクルが実行されるような処理を行えばthis.click
と同じような動きになる。
var global = 'hello, world'; angular.module('myapp', []) .controller('myController', function ($rootScope, $scope) { $rootScope.$watch( function () { console.log('監視処理が動く'); return global }, function (newValue, oldValue, scope) { console.log('globalが変更されました:' + newValue) ; }); this.click = function() { console.log('this.click'); global = new Date(); } this.dummy = function() { console.log('this.dummy'); } }); function changeValue() { console.log('changeValue'); global = new Date(); } function callApply() { console.log('callApply'); angular.element('#myCtrl').scope().$apply(); }
まとめ
$watchは監視処理を定義する
$digestサイクル内で監視処理を呼ぶ($rootScopeから先に呼ばれていたことから察すると$rootScope(親Scope)が優先順位が高いと思われる)
ng-clickなど$digestサイクルを呼ぶ処理がある(入力値を変えた時とかもおそらく呼ばれている=これがAngularのデータバインディングの正体か)