angularjs$watch旧值和新值相同
我的意图是观察范围内的模型,并找出旧值和新值之间的差异 但是,我从下面的代码中发现旧值和新值都是相同的angularjs$watch旧值和新值相同,angularjs,Angularjs,我的意图是观察范围内的模型,并找出旧值和新值之间的差异 但是,我从下面的代码中发现旧值和新值都是相同的 app.controller('MyCtrl', function($scope, $timeout){ $scope.markers = {}; $scope.$watchCollection('markers', function(newValue, oldValue){ console.log('being watched oldValue:', oldValue, 'n
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}
为什么它们是一样的,如果是故意的,为什么
下面是代码,您可以使用
$watch
来代替,这似乎很有效。如果您想同时查看对象上的所有属性(正如您所做的),则需要将true
作为第三个参数添加到监视中。这是一个深表
JS:
这是一个错误
而且它似乎不是固定的。这些值作为参数传递
$scope.$watch('foo', function (newValue, oldValue) {
// ...
}
我发现检查新值和旧值(值)是否相等非常有用,如果是这样,则跳过该过程以避免意外行为。你可以用它来实现这一点。下面是一个例子: JS:
watchCollection的文档说明:“Shallow监视对象的属性,并在任何属性更改时激发(对于数组,这意味着监视数组项;对于对象映射,这意味着监视属性)。”。因此,在对象上使用watchCollection是正确的。@JBNizet奇怪,我确实尝试先对watchCollection进行深度监视(添加true),但没有成功。不过,常规深度观察确实有效。:)我已经编辑了答案,所以我不会在这两个之间做假设。JB,watchCollection被破坏了。是的,当属性更改时触发,否,它不会保存旧值以返回它们,如文档中所指定。相反,您将在一个新的单独对象中获得新数据的副本。文档不是最新的,或者是一个bug
newValue===oldValue
声明false
,因此我倾向于认为这是一个bug。事实证明这是一个已知的bug:我假设$watchCollection是deep$watch的捷径。似乎不是。太好了,我浪费了十分钟的生命。谢谢你的提问,节省了我很多时间。:)现在已经修好了:当心!这是一种非常糟糕的做法,在某些情况下很容易导致问题。例如,当第一次设置监视的属性(即从未定义转换为某个值)时,将调用监视侦听器,并将newValue和oldValue bot设置为新值,如果存在此检查,则将忽略更改。您可以在此处阅读更多关于此的信息:
$scope.$watch('foo', function (newValue, oldValue) {
// ...
}
$scope.$watch('myObject', function(newValue, oldValue){
if(angular.equals(newValue, oldValue)){
return; // simply skip that
}
});