はじめに
$rootScopeに入れたプロパティを監視して、変更があったら◯◯したい場合がありました。
普通に$rootScope.$watch
で問題ないかと思っていたのですが、少し困ったことがあったのでメモしておきます。
困ったこと
例えば下記のような場合、$rootScope.myNameの変更を監視して、変更があったらalertを表示させます。
var app = angular.module('App', []);
app.controller('HogeCtrl', ['$rootScope', '$scope', function($rootScope, $scope) {
$rootScope.myName = '太郎';
$rootScope.$watch('myName', function() {
alert($rootScope.myName);
});
}]);
こちらで、問題なく動作するのですが、
なんらかの理由でHogeCtrl
がもう一度実行された場合に問題が起こります。
問題
何が問題かというと、$rootScope.myNameの変更があった場合、alertが2回表示されるようになります。
原因
原因としては、$rootScope.$watch
が実行される度に、rootScopeの$$watchersに監視対象が追加されていきます。
対象(myName)がすでに登録済みでも追加される為、myNameに変更があった場合、追加された監視対象分処理が実行されていたようです。
※正しい表現かが怪しいです。
当たり前の動作なのかもしれませんが、私は監視対象が同じ場合は上書きされるのかと思い込んでいました。
対応方法
rootScopeをwatchするのはやめて、下記のようにしました。
$watchの第一引数をプロパティ名ではなく、rootScopeのプロパティを返す関数に変更しました。
これで、コントローラーが2回実行されてもalertが2回おきることはなくなりました。
var app = angular.module('App', []);
app.controller('HogeCtrl', ['$scope', function($scope) {
$rootScope.myName = '太郎';
$scope.$watch(function(){return $rootScope.myName;}, function() {
alert($rootScope.myName);
});
}]);