我只是想为AngularJS提供一些概念验证。 在下面的代码中,由于某种原因,对getClass的调用将进入无限循环。 范围变量noOfCalls设置为在函数中递增。 我的期望是Angular在每次迭代时调用此函数一次。有人可以帮忙吗?
Plunker链接 http://plnkr.co/edit/7QvkSEQGTJtExwYm9kgD?p=preview
HTML
<body ng-controller="MainCtrl">
<h1>Total number of calls: {{noOfCalls}}</h1>
<div class="container" ng-repeat="item in arraydata">
<div class="form-group">
<input type="text" class={{getClass(item)}} ng-model=item.name />
</div>
</div>
</body>
控制器
var app = angular.module('angularjs-starter', []);
app.controller('MainCtrl', function($scope) {
$scope.arraydata = [];
$scope.arraydata.push({id:1, name: "test1"});
$scope.arraydata.push({id:2, name: "test2"});
$scope.arraydata.push({id:3, name: "test3"});
$scope.noOfCalls=0;
$scope.getClass = function(item)
{
$scope.noOfCalls+=1;
return("form-control");
}
});
答案 0 :(得分:2)
评估插值的次数不是您的控制器,而是框架。 Angular在称为摘要周期的过程中多次调用您的函数。此过程用于确定模型是否已更改为绑定的元素。
在您的情况下,您在插值noOfCalls
内定义的函数中递增{{getClass()}}
。这导致更改noOfCalls变量,该变量再次用于插值{{noOfCalls}}
。摘要循环继续运行或重新评估表达式,直到模型稳定或达到10次迭代。在上面的案例中,模型会一次又一次地使用getClass()
评估进行更新。
删除插值{{noOfCalls}}
,迭代不会发生。如果在插值或指令中调用需要评估表达式的函数,请保持函数方面免受影响。
答案 1 :(得分:0)
根本原因是@Chandermani回答所有表达式将重复运行,直到没有检测到任何变化。
仅出于教育目的,如果你真的想做类似的事情,你必须以某种方式找到打破循环的方法。例如。
var childScope = $scope.$new();
childScope.noOfCalls = 0;
$compile($element.find('h1'))(childScope);
$scope.getClass = function(item) {
setTimeout(function () {
childScope.noOfCalls++;
childScope.$digest(); // use $digest here to not trigger digest cycle of parent scopes
}, 0);
return("form-control");
};
示例plunker: http://plnkr.co/edit/d4TB6sh4Sc7MP7FrQyOV?p=preview
技巧是:
h1
标记,并将noOfCalls
标记存储在此新范围内。setTimeout
推迟noOfCalls
的增量,直到摘要周期结束。childScope.$digest()
更新视图中的h1
,但要避免触发父作用域的新摘要周期。