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