結論だけを知りたい場合:
$scope.$watch($rootScope.xxx,function(newVal,oldVal){ //do something })
誰かがすぐに、なぜそうしないのか尋ねました:
$rootScope.$watch("xxx",function(newVal,oldVal){ //do something })
私が最近遭遇したバグの最初の方法を使用する必要がある理由を説明しましょう。
ロジックは図の通りです。最初は$rootScope.$watchの記述方法を使用しました。 $rootScope 上の angularjs の監視は、一度登録されるとグローバルに有効になるためです。そして、私のグローバル変数は偶然にも注文情報です。これは、さまざまなコントローラーがその変数に変更を加えていることを意味し、すべての変更が $rootScope.$watch をトリガーして他のコントローラーに入るようにします。同様に、$rootScope 上の $broadcast がグローバルに開始されます。
実際には、これが唯一の方法ではありません。次のコードを含む Angular ソース コードをチェックすることで、watch メソッドのソース コードを見つけることは難しくありません。
return function deregisterWatch() { if (arrayRemove(array, watcher) >= 0) { incrementWatchersCount(scope, -1); } lastDirtyWatch = null; };
var watcher = $rootScope.$watch("xxx",function(){}); //手动清除 watcher watcher();
これを調査したときに、問題があると感じました。$scope はクリアされますか?そこで、引き続きソース コードを調べていくと、$destroy メソッドに次のコードが見つかりました。
// Disable listeners, watchers and apply/digest methods this.$destroy = this.$digest = this.$apply = this.$evalAsync = this.$applyAsync = noop; this.$on = this.$watch = this.$watchGroup = function() { return noop; }; this.$$listeners = {};