Controller function called twice with ng-show

I have a very simple installation of an Angular application, the code is as follows:

index.html

<!DOCTYPE html> <html> <head> <script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js'></script> <script src='app.js'></script> </head> <body ng-app="app"> <div ng-controller="MyCtrl"> <div ng-show="ready()"> Some content </div> </div> </body> </html> 

And app.js

 var app = angular.module('app', []); app.controller('MyCtrl', function($scope) { console.log("MyCtrl called") $scope.ready = function() { console.log("ready called"); return true; } }) 

If you run this with the console open, you will see that MyCtrl is called once and ready to be called twice. I spent hours trying to figure it out, I see no reason why $scope.ready will be called something, but exactly once.

If you use Angular v1.1.5 and use ng-if instead of ng-show , you will have the same behavior, but if you use ng-init , it correctly calls $scope.ready once. In my case, I will need ng-show or ng-if .

Plunkr: http://plnkr.co/edit/ZSwVNLeFSuhbouXZu9SM?p=preview

Explanation: To clarify what I am aiming for, say, $scope.ready returns false at some point later (perhaps it calls an AJAX call, which should NOT be called more than once), I would like some content was not longer to be visible. That is, dynamic behavior is based on the result of $scope.ready .

Any ideas? Thanks for the help!

For writing this and this, this is not a problem.

+6
source share
2 answers

This is by design, not an error (and it has nothing to do with the AngularJS compiler, since another answer is incorrectly specified). ng-show and ng-hide work by “viewing” changes to the ready() expression.

In each digest cycle, for each time zone, AngularJS evaluates the associated expression to see if there is any change, and if so, invoking the listener (in the case of ng-show / ng-hide , the listener will show or hide the element based on value returned by ready() ).

Now AngularJS cannot just be satisfied with the first value returned by ready() , because during the same digest cycle something (for example, another expression for the clock) can really make some changes that force everything that is ready() , be a different value (for example, by changing the isReady variable returned by ready() ). Obviously, the developers expected the last value to be reflected in the DOM.

Therefore, AngularJS will evaluate each clock expression at least once to make sure it is “stabilized” before the end of the digest cycle. Of course, this can lead to endless iteration of the digest if the expression continues to change, so AngularJS throws an error if the digest cycle cannot complete within 10 iterations.

+13
source

There was an error report on this, and the answer was related to the compiler performing a double check.

This is the expected behavior. AngularJS makes a call twice to ensure that the model has stabilized before it is rendered.

There should be more information on why this is here http://docs.angularjs.org/guide/compiler

Bug Report: https://github.com/angular/angular.js/issues/1146

+3
source

Source: https://habr.com/ru/post/953009/


All Articles