$ watch定义触发后很快消化$&$ 34; $申请已经在进行中......"错误

时间:2016-03-09 18:47:23

标签: javascript jquery angularjs

我是一个有角度的菜鸟,我正在努力理解为什么以下触发" $ apply已经在进行中......"错误。

这是代码(它几乎直接来自文档: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/

我得到了着名的&#34; $申请已经在进行中&#34;错误,但为什么会这样?

我想知道为什么摘要周期甚至没有被调用就会触发?

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

请指教。

2 个答案:

答案 0 :(得分:2)

name变量在watch yes之前设置,但所有watch在初始化时都会被调用一次:

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.
  }
});

答案 1 :(得分:1)

如果您确实需要拨打$ digest,可以使用

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

Fiddle