Implementing Custom Events in Nested Controllers

Listings 8.3 and 8.4 illustrate the use of $emit(), $broadcast(), and $on() to send and handle events up and down the scope hierarchy. In Listing 8.3, lines 2–15 implement a parent scope controller called Characters, and lines 16–32 define a child scope controller named Character.

Also in Listing 8.3, the changeName() function changes the currentName value and then broadcasts a CharacterChanged event. The CharacterChanged event is handled in lines 26–28, using the $on() method, and sets the currentInfo value in the scope, which will update the page elements.

Notice that line 6 of Listing 8.3 uses the this keyword to access the name property. The name property actually comes from a dynamic child scope that was created because the following directives were used to generate multiple elements in Listing 8.4. The child scope can be accessed from the changeName() method in the scope by using the this keyword:

ng-repeat="name in names"
ng-click="changeName()"

Lines 9–14 of Listing 8.3 implement a handler for the CharacterDeleted event that removes the character name from the names property. The child controller in line 27 broadcasts this event via $broadcast().

The AngularJS template code in Listing 8.4 implements the nested ng-controller statements, which generates the scope hierarchy and displays scope values for the characters. This code also includes some very basic CSS styling to make spans look like buttons and to position elements on the page. Figure 8.2 shows the resulting web page. As you click a character name, information about that character is displayed, and when you click the Delete button, the character is deleted from the buttons and the Info section.

Listing 8.3 scope_events.js: Implementing $emit() and $broadcast() Events within the Scope Hierarchy


01 angular.module('myApp', []).
02   controller('Characters', function($scope) {
03     $scope.names = ['Frodo', 'Aragorn', 'Legolas', 'Gimli'];
04     $scope.currentName = $scope.names[0];
05     $scope.changeName = function() {
06       $scope.currentName = this.name;
07       $scope.$broadcast('CharacterChanged', this.name);
08     };
09     $scope.$on('CharacterDeleted', function(event, removeName){
10       var i = $scope.names.indexOf(removeName);
11       $scope.names.splice(i, 1);
12       $scope.currentName = $scope.names[0];
13       $scope.$broadcast('CharacterChanged', $scope.currentName);
14     });
15   }).
16   controller('Character', function($scope) {
17     $scope.info = {'Frodo': { weapon: 'Sting',
18                               race: 'Hobbit'},
19                    'Aragorn': { weapon: 'Sword',
20                                 race: 'Man'},
21                    'Legolas': { weapon: 'Bow',
22                                 race: 'Elf'},
23                    'Gimli': { weapon: 'Axe',
24                               race: 'Dwarf'}};
25     $scope.currentInfo = $scope.info['Frodo'];
26     $scope.$on('CharacterChanged', function(event, newCharacter){
27       $scope.currentInfo = $scope.info[newCharacter];
28     });
29     $scope.deleteChar = function() {
30       delete $scope.info[$scope.currentName];
31       $scope.$emit('CharacterDeleted', $scope.currentName);
32     };
33   });


Listing 8.4 scope_events.html: HTML Template Code That Renders the Scope Hierarchy for Listing 8.3 Controllers


01 <!doctype html>
02 <html ng-app="myApp">
03   <head>
04     <title>AngularJS Scope Events</title>
05     <style>
06       span{
07         padding: 3px; border: 3px ridge;
08         cursor: pointer; width: 100px; display: inline-block;
09         font: bold 18px/22px Georgia; text-align: center;
10         color: white; background-color: blue }
11       label{
12         padding: 2px; margin: 5px 10px; font: 15px bold;
13         display: inline-block; width: 50px; text-align: right; }
14       .lList {
15         vertical-align: top;
16         display: inline-block; width: 130px; }
17       .cInfo {
18         display: inline-block; width: 175px;
19         border: 3px blue ridge; padding: 3px; }
20     </style>
21   </head>
22   <body>
23     <h2>Custom Events in Nested Controllers</h2>
24     <div ng-controller="Characters">
25       <div class="lList">
26           <span ng-repeat="name in names"
27                  ng-click="changeName()">{{name}}
28            </span>
29       </div>
30       <div class="cInfo">
31            <div ng-controller="Character">
32              <label>Name: </label>{{currentName}}<br>
33              <label>Race: </label>{{currentInfo.race}}<br>
34              <label>Weapon: </label>{{currentInfo.weapon}}<br>
35              <span ng-click="deleteChar()">Delete</span>
36            </div>
37       </div>
38     </div>
39     <script src="http://code.angularjs.org/1.3.0/angular.min.js"></script>
40     <script src="js/scope_events.js"></script>
41   </body>
42 </html>


Image

Figure 8.2 Using $broadcast() and $emit() to send change and delete events through a scope hierarchy.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset