簡體   English   中英

如何在AngularJS中觀看Scope上的所有更改?

[英]How to watch all changes on a Scope in AngularJS?

Angular的$ watch函數允許在指定的屬性更改時觸發事件,如下所示。 當范圍發生任何變化時,是否有類似的方式來監聽事件?

// works
$scope.$watch("someval", function() { }, true);
$scope.$watch(function(scope){ return scope.someval; }, function() { }, true);

// doesn't work
$scope.$watch("this", function() { }, true);
$scope.$watch(function(scope){ return scope; }, function() { }, true);

我相信你不能注意$scope變化(除了使用@ ValentynShybanov的消化)。 你最接近的事情是觀察摘要電話:

$scope.$watch(function() { 
    console.log("digest called"); 
});

每次在作用域上調用$digest都會調用上面的函數, 即使作用域的屬性沒有變化也是如此。

這不是直截了當的,因為范圍是一個普通的對象。 這是Backbone,您可以訂閱所有事件,但為此您的模型應擴展專有接口 - Backbone.Model Angular將觀察者模式放在它的經典外觀中。 這是一個不尋常的設計決定。 基本上有一個循環,其中Angular評估被監視的表達式,當它檢測到與前一次迭代的差異時,它會通知觀察者。 一種非常有趣的方法,可能是觀察者模式的唯一替代方法(除了可能是反應式編程 ,這種情況還不常見)。

我建議使用一個函數作為監視表達式,它返回范圍的哈希值。 不幸的是,范圍在某處包含循環引用,因此JSON.stringify($scope)等快速解決方案不起作用。 我寫了快速而骯臟的概念證明。 http://jsfiddle.net/ADukg/2544 無論您輸入什么文本字段,它都會打印到控制台。 String hash函數取自Javascript / jQuery中的字符串生成Hash

function MyCtrl($scope) {
    $scope.$watch(
        function($scope) {return hash($scope);},
        function() {console.log("changed");}
    );
}

我自己遇到了這個問題,我用類似於@ ValentynShybanov的評論解決了這個問題,但並不完全相同。 我的解決方案不要求您按照評論中的說明為所有屬性添加前綴

看到一個工作的plunkr

var entireScope = {};
  for ( var i in $scope ){
    if ( i[0] !== '$' && i !== 'this' && i !== 'constructor'){
      console.log(i);
      entireScope[i] = $scope[i];
    }
  }

  $scope.entireScope = entireScope;

  $scope.$watch('entireScope', function( newValue, oldValue ){
   $log.info('entireScope has changed',newValue, oldValue);
  }, true);

正如您所看到的那樣,解決方案完全相同,但實際上它會為范圍添加另一個屬性,而不是替換您已有的結構。 這個新屬性代表整個范圍(因此它的名字),你可以觀看它。

我編寫的循環可能過於通用,您可以使用自定義初始化替換它。 例如:

$scope.entireScope = { 'someVal' : $scope.someVal }

此解決方案可滿足您的需求,並使您無需重構代碼。

一個簡單的解決方案可能是您應該只檢查范圍的變量,但它可能是對象。

app.js

app.controller('MainController', ['$scope', function($scope){
   $scope.watchable = {
       'param1':'',
       'param2':''
   };
   $scope.update = -1;
   $scope.$watch('watchable', function(scope){
       scope.update++;
   }, true);

});

的index.html

<div ng-controller="MainController">
    <input type='text' ng-model="watchable.param1">
    <input type='text' ng-model="watchable.param2">
    <p>param1:{{watchable.param1}}, param2:{{watchable.param2}}</p>
    <p>update:{{update}}
</div>

這里的技巧是在$ watch函數的第三個參數中傳遞'true',它將執行angular.equal檢查,該檢查是按值檢查而不是簡單的引用檢查。 如果正確的話請告訴我。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM