角度控制器在init上被调用10次

时间:2014-05-02 14:45:44

标签: angularjs controller

我正处于学习AngularJS的早期阶段,并且看到了一种奇怪的行为。当我的页面加载时,相关的控制器被调用10次。我在这里有一个显示行为的fiddle。当您在输入框中输入一个字符时,您将看到它被称为另一个字符。

    <html>
<head>
<script
    src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.js"></script>
    <script type="text/javascript">
        var HelloCtrl = function($scope) {
            var keysTyped = 0;
            $scope.name = 'World';

            $scope.i = function() {
                return keysTyped++;
            };
        }
</script>Angular controller being called 10 times on init
</head>
<body ng-app>
    <div ng-controller="HelloCtrl">
        Say hello to: <input type="text" ng-model="name"/><br/>
        <h1>Characters typed, {{i()}}!</h1>
    </div>
</body>
</html>

2 个答案:

答案 0 :(得分:2)

首先,你看到它被正好调用10次,因为这是在角度抛出异常之前可以运行的$ digest循环的限制值。

通常在渲染过程中更改对象属性时会发生这种情况。这将触发一个新的渲染,因此循环将导致“10 $ digest()迭代达到。中止!”错误。 (a.k.a Infinite $ digest循环)

您可以解决此问题,将您的代码更改为:

    <div ng-controller="HelloCtrl">
            Say hello to: <input type="text" ng-model="name" ng-change="i()"/><br/>
    <h1>Characters typed, {{keysTyped}}!</h1>
</div>

并在您的控制器上:

     $scope.keysTyped = 0;

     $scope.i = function () {
        $scope.keysTyped++;
     };

我所做的只是利用Angular的双向绑定来解决问题。

我已经接受了您的代码并对其进行了修改,以使其正常工作并解释您为何获得Infinite $ digest循环。

如果你想要的只是在输入字段中有一个字符数,你需要做的就是:

    <body ng-app="">
        <div ng-controller="HelloCtrl">
            Say hello to: <input type="text" ng-model="name"/><br/>
    <h1>Characters typed, {{name.length || 0}}!</h1>
        </div>
    </body>

您不需要使用函数来计算字符数。

答案 1 :(得分:1)

您的代码中存在的问题称为无限摘要循环。 当您单击该按钮时,您不仅仅返回一个值,而是同时更新它,从而触发另一个摘要周期,触发另一个摘要周期,依此类推。这可能发生多达10次,然后抛出错误。如果你在那个小提琴上检查控制台,你就会在控制台上看到错误。

查看angularjs的文档。