我有一个ng-repeat
循环遍历属于SomeController
的对象数组:
<div ng-controller="SomeController as aCtrl">
<div ng-repeat="category in aCtrl.categories">
<p ng-show="aCtrl.checkShouldBeDisplayed(category)">{{category.name}}</p>
</div>
</div>
控制器定义为:
app.controller('SomeController', function() {
this.categories = [{
"name": "one",
}, {
"name": "two",
}, {
"name": "three",
}, {
"name": "four",
}];
this.counter = 0;
this.checkShouldBeDisplayed = function(channel) {
this.counter = this.counter + 1;
console.log("executing checkShouldBeDisplayed " + this.counter);
return true;
};
});
我希望checkShouldBeDisplayed
函数计为4,因为SomeController.categories
数组中有四个元素。相反,它计为8 - 在此处检查:http://plnkr.co/edit/dyvM49kLLTGof9O92jGb(您需要在浏览器中查看控制台以查看日志)。我怎样才能绕过这种行为?干杯!
答案 0 :(得分:3)
这是预期的;指令ng-repeat
将重复次数,因为框架认为是正确的;这称为脏检查,您可以在this post中阅读更多相关内容。
出于这个原因,最好是以声明的方式而不是强制性地思考。换句话说,方法checkShouldBeDisplayed
应该只执行它在锡上所说的内容,而不是依赖于调用它的次数。如果您需要执行某种聚合或操作,则应在控制器的其他位置执行。
答案 1 :(得分:1)
根据 the docs :
每次调用$ digest()时都会调用watchExpression,并应返回将要监视的值。 (由于$ digest()在检测到更改时重新运行,因此watchExpression可以每$ digest()执行多次,并且应该是幂等的。)
[...]
监听器可能会更改模型,这可能会触发其他侦听器触发。这是通过重新运行观察者直到没有检测到任何变化来实现的。
所有ngShow
都会注册观察者:
scope.$watch(attr.ngShow, function ngShowWatchAction(value){
$animate[toBoolean(value) ? 'removeClass' : 'addClass'](element, 'ng-hide');
});
你的函数是ngShow
的watch-expression,因此被执行两次:
1.在第一个$摘要中,它检测到新值
2.在第二个$摘要中,它验证没有任何变化并终止。
在此 short demo 中,您可以验证有两个$ digest循环。