Gleb
Gleb

Reputation: 1332

ng-repeat call controller function too many times

I have next code (events is array):

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

time-ago - my custom directive. It is executed events.length times.

My controller:

...
window.callPrepareAlertValueCount = 0

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

After list is shown - I see that callPrepareAlertValueCount grows. Console log:

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

Please, can someone explain why is prepareAlertValue executed all time. Do I need to write directives for each formatter function?

Upvotes: 3

Views: 2571

Answers (4)

Bijayakrishna Das
Bijayakrishna Das

Reputation: 21

You may stop calling controller functions inside ng-repeat. or if you want to call the controller function inside a loop(ng-repeat), then use proper conditions(in your controller), if true then call the function if you don't , then it will be calling the controller function every time.

Upvotes: -1

Pankaj Parkar
Pankaj Parkar

Reputation: 136154

That is correct what ever you bind on html, it gets called on each digest cycle run by angular js.

Use {{::prepareAlertValue(event.AlertValue)}} bind once directive that will execute that function only once.

Note Bind Once only work for above Angular 1.3+

Upvotes: 2

Omri Aharon
Omri Aharon

Reputation: 17064

callPrepareAlertValueCount is a global variable on the window, and is updated whenever prepareAlertValue function is called.

The catch is, it's called whenever a digest cycle takes place. Whenever a change is made, such as a click event is triggered (through Angular with ng-click), or your events array is altered, that triggers a $digest cycle. When a $digest is triggered, the function reevaluates as all angular watchers are being reevaluated, and increments callPrepareAlertValueCount. So it happens many more times than events.length.

Basically, you shouldn't be relying on keeping a counter that way, since you have no control on how many times the $digest cycles are run.

Here's a simple Fiddle that demonstrates this.

Upvotes: 0

goreorto
goreorto

Reputation: 302

Angular does not know whats going on inside prepareAlertValue() so it needs to call this function on every digest

Upvotes: 1

Related Questions