tomersss2
tomersss2

Reputation: 155

Angular.JS ng-Repeat in directive runs twice

https://plnkr.co/edit/WzLez5XElbOHRTvXEJFc?p=preview

      function DirectiveController($scope, $element)
 {
 $scope.Array = ["a", "b"];
    $scope.me = function() {
      console.log("i ran");
    };

};


 //Directive HTML
<div class="cool picker" ng-repeat="item in Array">
        <input ng-value="me()">
           {{item}}
        </input>
</div>

A function in directive controller is being called 4 times while directive runs only 2 times by ng-repeat. I created a thine version of my code in Plunker, so suggestions like "get rid of isolated scope won't help".

Upvotes: 0

Views: 824

Answers (1)

Yaser
Yaser

Reputation: 5719

What you are seeing is the digest cycle at work. The digest cycle is how Angular’s auto-update magic works – it’s the reason that typing into an input box automatically updates anything that refers to its value.

When the digest cycle runs, it effectively redraws everything that might have changed on the page.

Angular uses some tricks to find everything that might have changed, and the main technique is watchers. These watchers are created automatically when you use directives like ng-if and ng-class, and when you use bindings like {{ yourBindingHere }}.

Each one of those things registers a watcher. When Angular’s digest cycle runs, every watcher is asked to update its state. In the case of ng-class, it will re-run the function bound to it, to see if anything needs to change. This is why your controller function runs multiple times, and it’ll run again each time something changes on the page.

Now since you are using interpolation {{}} it forces Angular to run once, and using a function with ng-value forces it another time.

The best practice is to not use function inside ng-repeat since it always forces the cycle to check for an update.

And at last use one time binding where possible to prevent any watcher to be created.

Upvotes: 2

Related Questions