2013-12-23 83 views
24

我的目的是觀察範圍內的模型,並找出舊值和新值之間的差異。

但是,我發現舊值和新值都是從下面的代碼相同。

app.controller('MyCtrl', function($scope, $timeout){ 
    $scope.markers = {}; 
    $scope.$watchCollection('markers', function(newValue, oldValue){ 
    console.log('being watched oldValue:', oldValue, 'newValue:', newValue); 
    }); 
    $timeout(function() { 
    $scope.markers.foo = 1; 
    }, 500); 
    $timeout(function() { 
    $scope.markers.bar = 2; 
    }, 500); 
}); 

輸出:

being watched oldValue: Object {} newValue: Object {} script.js:6 
being watched oldValue: Object {foo: 1} newValue: Object {foo: 1} script.js:6 
being watched oldValue: Object {foo: 1, bar: 2} newValue: Object {foo: 1, bar: 2} 

爲什麼他們一樣的,如果是故意的,那麼爲什麼呢?

這裏是代碼,http://plnkr.co/edit/rfMCF4x6CmVVT957DPSS?p=preview

+0

無論是文檔,是達不到最新的或者是一個錯誤。 'newValue === oldValue'陳述'false',所以我傾向於認爲它是一個錯誤。 –

+4

原來這是一個已知的bug:https://github.com/angular/angular.js/issues/2621 – KayakDave

+0

我認爲$ watchCollection是deep $ watch的快捷方式。看起來不是。 – allenhwkim

回答

35

您可以使用$watch代替,這似乎工作。如果您想要觀察物體上的所有屬性(如您所做的那樣),則需要將true作爲第三個參數添加到手錶中。這設立了一個深刻的觀察。

Here is a working plunker.

JS:

app = angular.module('myApp',[]); 

app.controller('MyCtrl', function($scope, $timeout){ 
    $scope.markers = {}; 
    $scope.$watch('markers', function(newValue, oldValue){ 
    console.log('being watched oldValue:', oldValue, 'newValue:', newValue); 
    }, true); 
    $timeout(function() { 
    $scope.markers.foo = 1; 
    }, 500); 
    $timeout(function() { 
    $scope.markers.bar = 2; 
    }, 500); 
}); 
+0

watchCollection的文檔說:「只要觀察一個對象的屬性並在任何屬性發生變化時觸發(對於數組,這意味着要觀察數組項目;對於對象映射,這意味着要注意屬性)。」因此,在對象上使用watchCollection是正確的。 –

+0

@JBNizet奇怪的是,我確實試着先爲watchCollection做一個深度觀察(加上true),但它沒有奏效。雖然經常深入觀察。 :)我編輯了答案,所以我沒有在兩者之間做出假設。 –

+1

JB,watchCollection已損壞。是的,它會在屬性更改時觸發,否則它不保存舊值以返回它們,如文檔中所述。相反,您會在新的獨立對象中獲得新數據的副本。 https://github.com/angular/angular.js/issues/2621 – Noishe

1

的值作爲參數傳遞

$scope.$watch('foo', function (newValue, oldValue) { 
    // ... 
} 
12

我發現它是非常有用的檢查新舊值相等(價值觀),跳過過程,如果這是爲了避免出現意外行爲的情況。您可以使用angular.equals來實現。這裏有一個例子:

JS:

$scope.$watch('myObject', function(newValue, oldValue){ 
    if(angular.equals(newValue, oldValue)){ 
     return; // simply skip that 
    } 
});