Mastering Web Application

(Rick Simeone) #1
Chapter 11

A page will be rendered even if the configured limit of 10 turns per
$digest loop is exceeded. The error is not easy to spot till you inspect
a console so it might get unnoticed for a while. Still we should track
down and resolve issues linked to unstable models.

$digest loop and a hierarchy of scopes


Each turn of the $digest loop recomputes all the watch expressions on all scopes,
starting from the $rootScope. This might be counter intuitive at first, as one could
claim that it would be enough to recompute the only expression on a given scope, and
all of its children. Unfortunately, this could lead to UI being desynchronized with the
model. The reason is that changes triggered in one of the child scopes can influence
variables in a parent scope. Here is a simple example of an application with two scopes
(one $rootScope and another one created by the ng-controller directive):


<body ng-app ng-init='user = {name: "Superhero"}'>
Name in parent: {{user.name}}
<div ng-controller="ChildCtrl">
Name in child: {{user.name}}
<input ng-model='user.name'>
</div>
</body>

Changes to the model (user.name) are triggered from a child scope (one created by
the ng-controller directive), but are changing properties of an object defined on
the $rootScope.


Setups like this force AngularJS to evaluate all the watches, starting from the
$rootScope, and continue down to child scopes (using depth-first traversal). If
AngularJS had evaluated watches on a scope where changes were triggered (plus
its children) it would have risked desynchronizing model values with the actual
display. In the example discussed here, the Name in parent: {{user.name}}
interpolation expression would not be evaluated and displayed correctly.


In each and every turn of the $digest loop AngularJS needs to
evaluate all the watches in all scopes. It does so starting from the
$rootScope and traversing child scopes depth-first.
Free download pdf