Join the Stack Overflow Community
Stack Overflow is a community of 6.7 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

I have defined a function on scope. And when I call it from the view inside {{}} it executes X number of times.

Controller

function testCtrl($scope) {
   $scope.myFunc = function(name) {
       return "Hello " + name;
   }
}

HTML

<div>{{myFunc('Joe')}}</div>

You can see it in this example: http://jsfiddle.net/rbRvD/2/

Or with Plunker: http://plnkr.co/edit/LLQ7cKs2fEoBwv0C5XPE

I guess this is done the wrong way, but why is it executed so many times?

share|improve this question
    
Setup a plunker. – Stewie Jun 18 '13 at 9:53
    
Updated with plunker link – hesa Jun 19 '13 at 5:57
    
Can you tell how you skip over this problem exactly ? – user2099451 Jul 26 '16 at 7:03
up vote 23 down vote accepted

Your function is run 10 times. Why 10? Why not 100?

The answer is in the docs:

The watch listener may change the model, which may trigger other listeners to fire. This is achieved by rerunning the watchers until no changes are detected. The rerun iteration limit is 10 to prevent an infinite loop deadlock.

When you see this happening, it means you are changing the model in such a way that Angular has to rerun the digest and fire the watches again. In your particular case you are calling a function that updates a counter, which is displayed on the page. When the counter value changes it runs the digest again, which calls the function that updates the counter, etc, etc.

Angular expects you (and indeed encourages you) to change the model and let the view respond to those changes, rather than the other way around.

share|improve this answer
    
Thanks for your response. – hesa Jun 19 '13 at 6:30
    
Missed this part in my response... Ok, then it's not an issue, I guess? The counter was just an example to make it clearer. With a log I suppose it would have logged one time for each watcher? – hesa Jun 19 '13 at 6:43

This is expected behaviour. Angular expressions ({{expression}}) are re-evaluated on each $digest loop (sometimes multiple times per loop). This means that expressions should stay light in computational terms.

For that matter, expression evaluation should not result in an AJAX call or some other intensive or asynchronous operation, or if it has to, than you should be caching the results.

share|improve this answer
    
zetetic's answer is technically correct but it answers the plunkr, not the question posted here(they are different). This answer is for the question posted here. – Sacho Apr 22 '15 at 8:36

AngularJs does not suggest you to change scope's model on rendering. If you want to change your scope's model, do it in Controller or Directive.

Think of view as a place to display data (scope values in this case) only, all the modifying of the data should be in Controller or Directive.

share|improve this answer
    
If you mean the counter value its only there to make my example clearer. You could put a log there instead. – hesa Jun 19 '13 at 7:15

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.