【问题标题】:Deep $watch vs $watchCollection: $var behavior深度 $watch 与 $watchCollection:$var 行为
【发布时间】:2014-12-11 20:55:18
【问题描述】:

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

【问题讨论】:

  • 我相信$watchCollection是看arrayLike对象。 $watchCollection is the preferred (and only) way to shallow watch an object ?我想你可以只使用不带第三个参数的 watch 来浅表观察。
  • @PSL watch 没有第三个参数只检查对象引用而不是相等性。所以var a = {};a.newProp = 1; 不会触发它,因为a == a; 仍然是true。而且 $watchCollection 也不限于 arrayLike 对象;(
  • 啊我忘了...
  • 为此我在 github 上发起了一个问题:github.com/angular/angular.js/issues/10426

标签: javascript angularjs angularjs-scope


【解决方案1】:

取自angular$watch源代码cmets:

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

【讨论】:

  • 谢谢。我发现我必须更改一行以使 $watchCollection 行为相似但不能让自己修改源代码!
  • 哈哈,是的,不幸的是,看起来没有任何东西可以传递给$watchCollection,无需实际修改即可获得该行为。我知道如果您愿意,Angular 团队非常擅长响应向他们发送拉取请求!
猜你喜欢
  • 2014-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-21
  • 1970-01-01
  • 2018-12-11
  • 1970-01-01
相关资源
最近更新 更多