Deep $ watch vs $ watchCollection:$ var行为

时间:2014-12-11 20:55:18

标签: javascript angularjs angularjs-scope

$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'

1 个答案:

答案 0 :(得分:1)

取自角度$watch源代码注释:

  

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

我们可以从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