【问题标题】:Performance: Why does AngularJS evaluate watch when scope model hasn't changed?性能:当范围模型没有改变时,为什么 AngularJS 会评估手表?
【发布时间】:2014-01-21 14:06:30
【问题描述】:

所以我对范围 A 有一个监视。为什么当同级范围 B 上的局部变量发生变化时 AngularJS 会评估它?范围A的数据模型没有改变。

这是一个最小的例子:

  • 范围 A 上有一个自定义手表。
  • 输入元素绑定到作用域 B 的 text 变量。
  • 请注意,text 未显示,因为它在范围 A 中不可见。

控制器:

function Ctrl1($scope) {

    console.log($scope); // first scope

    // my custom watch expression
    var count = 0;
    $scope.$watch(function() {
        count++;
        console.log("call count: " + count);
    }, function() {
        // the listener does nothing
        // I'm just interested in when the watch expression is called
    });

}

function Ctrl2($scope) {        
    console.log($scope); // second scope        
}

HTML:

<div ng-app>
    <div ng-controller="Ctrl1">        
        {{text}}
    </div>
    <div ng-controller="Ctrl2">
        <input type="text" ng-model="text"></input>
    </div>
</div>

(请随时在此处尝试此代码:http://jsfiddle.net/s3Wz5/4/

如果您在输入元素(范围 B)中键入一些文本,则会评估范围 A 的自定义监视。为什么是这样?为什么 AngularJS 不知道作用域 A 的数据模型没有任何变化?

更新:一些说明: 我不想看text。这是一个与性能相关的问题,想知道为什么即使无法从其他范围读取 text 也会评估手表!

【问题讨论】:

    标签: performance angularjs scope watch


    【解决方案1】:

    因为$watch 在每个摘要循环中都会被评估。更改ng-model 的值会触发摘要循环。此行为与 $scope.$digest() 不同,后者仅触发当前作用域和子作用域的消化。

    我认为ng-model 可能不会在内部使用$scope.$digest()。它可能会在值更改后使用其他一些机制来触发摘要。

    【讨论】:

    • 如果我理解正确,digest 只是调用当前作用域和子作用域中的手表。我在问为什么在兄弟作用域上调用它?
    • @Chris 当用户更改 ng-model 的值时,我认为 Angular 无法确定属性附加到的范围级别。因此,无法仅针对特定范围(及其子范围)触发摘要。
    • @Chris 我知道$scope.$digest() 只在当前和子范围内触发摘要,但这并不意味着ng-model 将在内部使用$digest
    • 我明白了。这对于更大的网页来说是不幸的=/如果您编辑答案以包含您的 cmets,我会接受它作为答案
    猜你喜欢
    • 2019-01-21
    • 1970-01-01
    • 1970-01-01
    • 2010-12-04
    • 2012-12-03
    • 1970-01-01
    相关资源
    最近更新 更多