Emitting and Broadcasting Events

A great feature of scopes is the ability to emit and broadcast events within the scope hierarchy. Events allow you to send notification to different levels in the scope that an event has occurred. Events can be anything you choose, such as a value changed or threshold reached. This is extremely useful in many situations, such as letting child scopes know that a value has changed in a parent scope or vice versa.

To emit an event from a scope, you use the $emit() method. This method sends an event upward through the parent scope hierarchy. Any ancestor scopes that have registered for the event are notified. The $emit() method uses the following syntax, where name is the event name and args is zero or more arguments to pass to the event handler functions:

scope.$emit(name, [args, . . .])

You can also broadcast an event downward through the child scope hierarchy by using the $broadcast() method. Any descendent scopes that have registered for the event are notified. The $broadcast() method uses the following syntax, where name is the event name and args is zero or more arguments to pass to the event handler functions:

scope.$broadcast(name, [args, . . .])

To handle an event that is emitted or broadcasted, you use the $on() method. The $on() method uses the following syntax, where name is the name of the event to listen for:

scope.$on(name, listener)

The listener parameter is a function that accepts the event as the first parameter and any arguments passed by the $emit() or $broadcast() method as subsequent parameters. The event object has the following properties:

Image targetScope: The scope from which $emit() or $broadcast() was called.

Image currentScope: The scope that is currently handling the event.

Image name: The name of the event.

Image stopPropagation(): A function that stops the event from being propagated up or down the scope hierarchy.

Image preventDefault(): A function that prevents default behavior in a browser event but only executes your own custom code.

Image defaultPrevented: A Boolean that is true if event.preventDefault() has been called.

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

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

Notice that line 6 of Listing 22.6 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 22.7. 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 22.6 implement a handler for the CharacterDeleted event that removes the character name from the names property. The child controller in line 27 sends this event via $emit().

The AngularJS template code in Listing 22.7 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 22.3 shows the resulting webpage. 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 22.6 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', race:'Hobbit'},
18                    'Aragorn':{weapon:'Sword', race:'Man'},
19                    'Legolas':{weapon:'Bow', race:'Elf'},
20                    'Gimli':{weapon:'Axe', race:'Dwarf'}};
21     $scope.currentInfo = $scope.info['Frodo'];
22     $scope.$on('CharacterChanged', function(event, newCharacter){
23       $scope.currentInfo = $scope.info[newCharacter];
24     });
25     $scope.deleteChar = function() {
26       delete $scope.info[$scope.currentName];
27       $scope.$emit('CharacterDeleted', $scope.currentName);
28     };
29   });


Listing 22.7 scope_events.html: HTML template code that renders the scope hierarchy for Listing 22.6 controllers


01 <!doctype html>
02 <html ng-app="myApp">
03   <head>
04     <title>AngularJS Scope Events</title>
05     <style>
06       div{padding:5px; font: 18px bold;}
07       span{padding:3px; margin:12px; border:5px ridge;
08            cursor:pointer;}
09       label{padding:2px; margin:5px; font: 15px bold;}
10       p{padding-left:22px; margin:5px; }
11     </style>
12   </head>
13   <body>
14     <div ng-controller="Characters">
15       <span ng-repeat="name in names"
16             ng-click="changeName()">{{name}}</span>
17       <div ng-controller="Character"><hr>
18         <label>Name: </label><p>{{currentName}}</p>
19         <label>Race: </label><p>{{currentInfo.race}}</p>
20         <label>Weapon: </label><p>{{currentInfo.weapon}}</p>
21         <span ng-click="deleteChar()">Delete</span>
22       </div>
23     </div>
24     <script src="http://code.angularjs.org/1.2.9/angular.min.js"></script>
25     <script src="/js/scope_events.js"></script>
26   </body>
27 </html>


Image

Figure 22.3 Using $brodcast() 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
18.221.19.26