$watchCollection是否可以忽略对以$开头的属性的更改?使用深度$watch时已经存在此行为,因为它依赖angular.equals进行比较。

理想情况下,$watchCollection是浅看对象的首选(也是唯一)方法。不同的行为有道理吗?



$scope.foo = {
  $bar: 'someValue',
  baz: 123456
};

$scope.$watch('foo', function() {
   console.log('watch');
}, true);

$scope.$watchCollection('foo', function(){
   console.log('watchCollection');
});

// logs 'watch'
// logs 'watchCollection'
$scope.foo.baz = 654321;

// logs 'watchCollection'
$scope.foo.$bar = 'changed'

最佳答案

取自有角的$watch源代码注释:


  当objectEquality == true时,根据{@link angular.equals}函数确定watchExpression的不等式。


我们可以从angular.equals文档中看到:


  在属性比较期间,将忽略函数类型的属性和名称以$开头的属性。


因此,这说明了为什么$watch比较会忽略$属性。

$watchCollection函数实际上是自己进行比较,以检查对象是否相同,它们是否为数组以及它们是否为数组,它会检查值是否相同。直接从源代码中获取:

if (oldLength !== newLength) {
    // if lengths do not match we need to trigger change notification
    changeDetected++;
    oldValue.length = oldLength = newLength;
}
// copy the items to oldValue and look for changes.
for (var i = 0; i < newLength; i++) {
    oldItem = oldValue[i];
    newItem = newValue[i];

    bothNaN = (oldItem !== oldItem) && (newItem !== newItem);
    if (!bothNaN && (oldItem !== newItem)) {
        changeDetected++;
        oldValue[i] = newItem;
    }
}


我不能说他们是否有意以这种方式实现了,但是那肯定是如何实现的= D

关于javascript - Deep $ watch vs $ watchCollection:$ var行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27432193/

10-09 09:06