A great feature of scopes is that they are organized in a hierarchy. The hierarchy helps you keep scopes organized and relevant to the context of the view they represent. Also, the $digest()
method uses the scope hierarchy to propagate scope changes to the appropriate watchers and the DOM elements.
Scope hierarchies are created automatically based on the location of ng-controller
statements in the AngularJS template. For example, the following template code defines two <div>
elements that create instances of controllers that are siblings:
<div ng-controller="controllerA"> . . . </div>
<div ng-controller="controllerB"> . . . </div>
However, the following template code defines controllers where controllerA
is the parent of controllerB
:
<div ng-controller="controllerA">
<div ng-controller="controllerB"> . . . </div>
</div>
You can access the values of parent scopes from a controller, but you can’t access the values of sibling or children scopes. If you add a property name in a child scope, which duplicates a property name in the parent scope, it does not overwrite the parent, but creates a property of the same name in the child scope that has a different value from the parent.
Listings 22.4 and 22.5 implement a basic scope hierarchy to demonstrate how scopes work in a hierarchy. Listing 22.4 creates an application with three controllers, each with two scope items defined. They all share the common scope property title
and the scope properties valueA
, valueB
, and valueC
.
Listing 22.5 creates the three controllers in an AngularJS template. Figure 22.2 shows the rendered AngularJS application. Notice that the value of the title
property in all three scopes is different. That is because a new title
property is created for each level in the hierarchy.
Lines 17–19 display the valueA
, valueB
, and valueC
properties. These values are read from three different levels in the scope hierarchy. The application shows that as you increment the value in the parent scope, a DOM element in a child controller is updated with the new value.
01 angular.module('myApp', []).
02 controller('LevelA', function($scope) {
03 $scope.title = "Level A"
04 $scope.valueA = 1;
05 $scope.inc = function() {
06 $scope.valueA++;
07 };
08 }).
09 controller('LevelB', function($scope) {
10 $scope.title = "Level B"
11 $scope.valueB = 1;
12 $scope.inc = function() {
13 $scope.valueB++;
14 };
15 }).
16 controller('LevelC', function($scope) {
17 $scope.title = "Level C"
18 $scope.valueC = 1;
19 $scope.inc = function() {
20 $scope.valueC++;
21 };
22 });
01 <!doctype html>
02 <html ng-app="myApp">
03 <head>
04 <title>AngularJS Scope Hierarchy</title>
05 </head>
06 <body>
07 <div ng-controller="LevelA">
08 <h3>{{title}}</h3>
09 ValueA = {{valueA}} <input type="button" ng-click="inc()" value="+" />
10 <div ng-controller="LevelB"><hr>
11 <h3>{{title}}</h3>
12 ValueA = {{valueA}}<br>
13 ValueB = {{valueB}}
14 <input type="button" ng-click="inc()" value="+" />
15 <div ng-controller="LevelC"><hr>
16 <h3>{{title}}</h3>
17 ValueA = {{valueA}}<br>
18 ValueB = {{valueB}}<br>
19 ValueC = {{valueC}}
20 <input type="button" ng-click="inc()" value="+" />
21 </div>
22 </div>
23 </div>
24 <script src="http://code.angularjs.org/1.2.9/angular.min.js"></script>
25 <script src="/js/scope_hierarchy.js"></script>
26 </body>
27 </html>