【问题标题】:$digest soon after $watch definition triggers "$apply already in progress..." error在 $watch 定义触发“$apply already in progress...”错误后不久,$digest
【发布时间】:2016-03-09 18:47:22
【问题描述】:

我是一个有角度的菜鸟,我试图理解为什么下面会触发“$apply is already in progress ...”错误。

这是代码(实际上几乎直接来自文档:https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$digest

<!DOCTYPE html>
<html>

<head>
    <script src="js/lib/angular.js"></script>
    <script>
    var app = angular.module('app', []);
    app.controller('MainController', ['$scope', function(scope) {
        scope.name = 'misko';
        scope.counter = 0;
        //A
        scope.$watch('name', function(newValue, oldValue) {
            scope.count++;
        });
        //B
        scope.$digest();
    }]);
    </script>
</head>

<body>
    <div ng-app='app' ng-controller="MainController">
    </div>
</body>

</html>

还有,这里是小提琴:https://jsfiddle.net/zLny2faq/5/

我收到了臭名昭著的“$apply already in progress”错误,但这是为什么呢?

我想知道为什么摘要循环在没有被调用的情况下触发?

换句话说,我只是声明监视侦听器 (@comment A) 并通过调用 $digest() (@comment B) 来触发它们。但是,当我明确调用 $digest() 时,它似乎以某种方式被更快地调用并且出错了。为什么会这样?

请指教。

【问题讨论】:

  • 您的代码没有多大意义。你为什么要调用scope.$digest()? $watch 已经被触发,因为您设置了 name 变量。一般来说,您只需要在角度框架之外调用 $digest/$apply,例如在单元测试中。
  • @dz210 这段代码实际上几乎是直接来自文档......但不是真的在 $watch 之前设置了 name 变量。

标签: javascript jquery angularjs


【解决方案1】:

name 变量是在手表之前设置的,但是所有手表都会在初始化时调用一次:

Per Angular Docs

在观察者注册到作用域后,监听器 fn 是 异步调用(通过 $evalAsync)来初始化观察者。在 在极少数情况下,这是不可取的,因为在调用监听器时 watchExpression 的结果没有改变。检测这种情况 在侦听器 fn 中,您可以比较 newVal 和 oldVal。如果 这两个值是相同的(===)然后监听器被称为到期 初始化。

^ 可以照顾via:

$scope.$watch('name', function(newValue, oldValue) {
  if (newValue !== oldValue) {
    // will only run if the value changes, on initial load the newvalue = oldvalue so it won't run this code.
  }
});

【讨论】:

    【解决方案2】:

    如果确实需要调用$digest,可以使用

    $timeout(function(){
        scope.$digest();
    }, 0);
    

    Fiddle

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多