Help us understand the problem. What is going on with this article?

$rootScopeを$watchしてたら困ったことメモ

More than 3 years have passed since last update.

はじめに

$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); 
  });

}]);
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした