ng-repeat呼叫控制器功能次数过多

时间:2015-02-27 18:46:22

标签: javascript angularjs angularjs-ng-repeat angular-digest

我有下一个代码(事件是数组):

<tr ng-repeat="event in events">
    <td>
        <span time-ago="{{event.TimestampSec}}"></span>
    </td>
    <td>
        {{prepareAlertValue(event.AlertValue)}}
    </td>
</tr>

time-ago - 我的自定义指令。它被执行 events.length 次。

我的控制器:

...
window.callPrepareAlertValueCount = 0

$scope.prepareAlertValue = function(value) {
    window.callPrepareAlertValueCount++;
    if(safemineHelper.isFloat(value)) {
        value = (~~(value * 100)) / 100;
    }
    return value;
}
...

显示列表后 - 我看到 callPrepareAlertValueCount 增长。控制台日志:

 > callPrepareAlertValueCount
 < 41890
 > callPrepareAlertValueCount
 < 46150
 > callPrepareAlertValueCount
 < 480315

请有人解释为什么prepareAlertValue一直执行。 我是否需要为每个格式化程序函数编写指令?

4 个答案:

答案 0 :(得分:2)

无论你在html上绑定什么都是正确的,它会在每个由角度js运行的摘要周期中被调用。

使用{{::prepareAlertValue(event.AlertValue)}} bind once指令只执行一次该函数。

  

注意绑定一次仅适用于上面的Angular 1.3 +

答案 1 :(得分:1)

Angular不知道prepareAlertValue()里面发生了什么 它需要在每个摘要上调用此函数

答案 2 :(得分:0)

callPrepareAlertValueCount是窗口上的全局变量,每当调用prepareAlertValue函数时都会更新。

抓住的是,每当发生摘要周期时都会调用它。每当进行更改时,例如触发点击事件(通过Angular with ng-click),或者您的events数组被更改,就会触发$ digest周期。当触发$ digest时,该函数会重新评估所有角度观察者的重新评估,并递增callPrepareAlertValueCount。所以它比events.length发生的次数多得多。

基本上,你不应该依赖这种方式保持计数器,因为你无法控制$ digest周期运行的次数。

这是一个简单的Fiddle,可以证明这一点。

答案 3 :(得分:-1)

您可以停止在ng-repeat内调用控制器功能。或者如果你想在一个循环中调用控制器函数(ng-repeat),那么使用适当的条件(在你的控制器中),如果为true则调用该函数,如果你没有,那么它将每次调用控制器函数