I'm very confused when a digest cycle is happening, is it called periodically based on a timer every 50ms (as it says here and implied here) or is it called after every event that enters the angular context (as it says here, here and here) ?
Example when it is matter:
In my model, I have a variable called myVar
with the value of 3. In my HTML, I have {{myvar}}
. An event such as a button click is fired and raises a handler in the controller, the code inside the handler is:
$scope.myVar = 4; // some heavy actions takes place for 3 seconds... $scope.myVar = 5;
Assuming the UI thread is not blocked, what will the user see after the button click? will he see only 5 or will he see 4 and after 3 seconds 5?
Digest cycle is what Angular JS triggers when a value in the model or view is changed. The cycle sets off the watchers which then match the value of model and view to the newest value. Digest cycle automatically runs when the code encounters a directive.
The $digest() function is called whenever AngularJS thinks it is necessary. For instance, after a button click handler has been executed, or after an AJAX call returns (after the done() / fail() callback function has been executed).
It again performs the second cycle of dirty checking on the previous cycle, watches listeners. Because there may have been variables that have got changed by others. Minimum 2 iterations are performed and the maximum 10 can run. Although it is preferred to minimize the digest cycle for better performance.
To answer your question, scope. $parent. $digest() will trigger a digest on scope 's parent.
I think the description of the digest cycle at http://blog.bguiz.com/post/60397801810/digest-cycles-in-single-page-apps that it is
code that runs at an interval
is very misleading, and to be honest, when referring to Angular, I would even say wrong. To quote Pawel Kozlowski, Mastering Web Application Development with AngularJS
AngularJS does not use any kind of polling mechanism to periodically check for model changes
To prove there is no polling, if you have a template of
<p>{{state}}</p>
and controller code of
$scope.state = 'Initial'; // Deliberately *not* using $timeout here $window.setTimeout(function() { $scope.state = 'Changed'; },1000);
as in this plunker, then the string shown to the user will remain as Initial
and never change to Changed
.
If you're wondering why you often see calls to $apply
, but not always, it is probably because the various directives that come with Angular, such as ngClick
or ngChange
will call $apply
themselves, which will then trigger the cycle. Event listeners to native JS events directly will not do this, so they will have to deliberately call $apply
to have any changes made reflected in templates.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With