2013-12-23 12 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

これは既知のバグです:https://github.com/angular/angular.js/issues/2621 – KayakDave

+0

$ watchCollectionは深い$ watchのショートカットであると仮定しました。そうではないようです。 – allenhwkim

答えて

35

あなたは仕事に思われる、代わりに$watchを使用することができます。オブジェクトのすべてのプロパティも(実行中に)監視したい場合は、trueを時計の3番目のパラメータとして追加する必要があります。これは深い時計を設定します。

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のドキュメントはこう書いています: "Shallowはオブジェクトのプロパティを監視し、いずれかのプロパティが変更されたときに起動します(配列の場合、配列アイテムを見ていることを意味します。したがって、オブジェクトに対してwatchCollectionを使用することは正しいです。 –

+0

@JBNizet奇妙なことに、私は最初にwatchCollectionの深い腕時計を追加しようとしましたが、それは機能しませんでした。レギュラーディープウォッチはやったけど。 :)私は答えを編集したので、私は2つの間で仮定をしていません。 –

+1

JB、watchCollectionが壊れています。はい、プロパティが変更されたときに起動します。いいえ、ドキュメントに指定されているように、古い値を返して保存しません。代わりに、新しいデータのコピーを新しい独立したオブジェクトに入れます。 https://github.com/angular/angular.js/issues/2621 – Noishe

5

これはバグです。

https://github.com/angular/angular.js/issues/2621

、それが固定されていないようです。私はそれが新しいと古い値が(値で)同じであるかどうかを確認し、それが予期しない動作を回避するために、ケースの場合、プロセスをスキップすることは非常に便利だことがわかっ

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

修正されました:https://github.com/angular/angular.js/issues/2621#issuecomment-37981379 – Itchy

1

値が渡されます。あなたはそれを達成するためにangular.equalsを使うことができます。ここでは例です:

JS:

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

パラメータとして

関連する問題