Tuesday 22 December 2015

Event based communication between controllers

Event based communication between controllers.


Every angular application has a single root Scope ($rootScope). All the scopes are its descendants.

Scopes can generate an  events by emitting ($emit) or broadcasting ($broadcast). Apart from generating events, scope can listen to events as well. Its is achieved by using the $scope.$on 

$emit, $broadcast and $on follow the standard "publish / subscribe" design pattern.


Understanding the $scope methods for event based communication between angular controllers

  • $scope.$emit:  This method dispatches the event in the upwards direction (from child to  parent)
  • $scope.$broadcast: Method dispatches the event in the downwards direction (from parent to child)  to all the child controllers.
  • $scope.$on: Method registers to listen to some event. All the controllers which are listening to that event gets notification of the broadcast or emit based on the where those fit in the child parent hierarchy.  

If we consider a case where "grand_child" controller calls the $emits method on its scope. The same "grand_child" controller has also listening to the same event which is emitted by itself. In this situation when "grand_child" calls $emit, the same controller gets its own notification. 

Essentially all the controllers in the hierarchy gets notification for $emit (in upwards direction).
Note : In case of sibling scopes (the scopes which are not in the direct parent child hierarchy) then $emit and $broadcast will not communicate to the sibling scopes.



$rootScope.$broadcast:  $rootScope is the parent of all the scopes. $rootScope.$broadcast will notify the event to all the controllers listening to $rootScope.$on as well as $scope.on



$rootScope.$emit :  We may think that calling $emit method is meaning-less as rootScope do not have any parent. But actually $rootScope.$emit fires an event to all the controllers listening $rootScope.$on event.  The controllers which are listening on $scope.$on have no effect of this emit.




Stopping the event being propagating 

The $emit event can be cancelled by any one of the $scope who is listening to the event.
The $on provides the "stopPropagation" method. By calling this method the event can be stopped from propagating further.

This method is available only for the events which are emitted($emit). The same is not available for $broadcast.

The events which are broadcast can't be stopped. Although we can registered the scope from listening the event. 
$on function returns a function.
.controller('T1Parent',['$scope',function($scope){
   $scope.T1EventVar = '';
   $scope.stopPropagation=false;
   $scope.stopBroadcast = false;
   var fn = $scope.$on('Tree1Event',function(e,arg){
	$scope.T1EventVar = arg;
	if($scope.stopPropagation) {
		e.stopPropagation();  
	}
	if($scope.stopBroadcast){
		fn();  // This will cancel the listening of the event 'Tree1Event'
	}
   });
   $scope.broadCastEvent=function(){
	 $scope.$broadcast('Tree1Event','T1 Parent Brodacated');
   };
   $scope.emitEvent=function(){
	 $scope.$emit('Tree1Event','T1 Parent Emitted');
   };
}])

The complete example can be see on the following plunk. This example demonstrates the emit, broadcast, rootScope.$emit, rootScope.$broadcast, stopping the propagation and cancelling the listening of the event from a particular controller's scope.

Demo http://plnkr.co/edit/0Pdrrtj3GEnMp2UpILp4?p=preview


source code emit-vs-broadcast.js


angular.module('dlgDemo',[])
.controller('GrandParent1',['$scope','$rootScope',function($scope,$rootScope){
   $scope.GrandParent1Var = '';
   //Listening the Tree 1 Child Event
   $scope.$on('T1childEmitEvent',function(e,arg){
	console.log("Hello");
	$scope.T1EventVar = arg;
   });
	// Listening to Tree 2 Grand Parent Event
   $scope.$on('Tree1Event',function(e,arg){
	$scope.T1EventVar = arg;
   });
   $scope.broadCastEvent=function(){
	   console.log("broadCastEvent");
	 $scope.$broadcast('Tree1Event','T1 Grand Parent Brodacated');
   };
   $scope.emitEvent=function(){
	 $scope.$emit('Tree1Event','T1 Grand Parent Emitted');
   };
   $scope.rootBroadcast = function() {
	   $rootScope.$broadcast('Tree1Event','$rootScope.$broadcast');
   };
   $scope.rootEmit = function() {
	   $rootScope.$emit('Tree1Event','$rootScope.$emit');
   };
}])
.controller('T1Parent',['$scope',function($scope){
   $scope.T1EventVar = '';
   $scope.stopPropagation=false;
   var fn = $scope.$on('Tree1Event',function(e,arg){
	   console.log(e);
	$scope.T1EventVar = arg;
	if($scope.stopPropagation) {
		e.stopPropagation();
	}
	if($scope.stopBroadcast){
		fn();
	}
   });
   $scope.broadCastEvent=function(){
	 $scope.$broadcast('Tree1Event','T1 Parent Brodacated');
   };
   $scope.emitEvent=function(){
	 $scope.$emit('Tree1Event','T1 Parent Emitted');
   };
}])

.controller('T1Child',['$scope','$rootScope',function($scope,$rootScope){
	$scope.T1EventVar = '';
	$scope.T1EventVarFromRoot = '';
   $scope.$on('Tree1Event',function(e,arg){
	console.log(e);
	$scope.T1EventVar = arg;
   });
   
   $scope.emitEvent = function() {
	$scope.$emit('Tree1Event','T1 Child Emitted');
   };

   $scope.broadCastEvent=function(){
	 //$scope.$broadcast('Tree1Event','T1 Child Brodacated');
	 $rootScope.$broadcast('Tree1Event','$rootScope.$broadcast');
   };
   $rootScope.$on('Tree1Event',  function(e,arg){
	   $scope.T1EventVar = arg;
   });
   
}])

.controller('GrandParent2',['$scope',function($scope){
   $scope.T1EventVar = '';
   //Listening the Tree 1 Child Event
   $scope.$on('Tree1Event',function(e,arg){
	$scope.T1EventVar = arg;
   });

   $scope.broadCastEvent=function(){
	 $scope.$broadcast('Tree1Event','T2 Grand Parent Brodacated');
   };

   $scope.emitEvent=function(){
	 $scope.$emit('Tree1Event','T2 Grand Parent Emitted');
   };
}])
.controller('T2Parent',['$scope',function($scope){
   $scope.T1EventVar = '';
   $scope.$on('Tree1Event',function(e,arg){
	$scope.T1EventVar = arg;
   });
   
   $scope.emitEvent = function() {
	$scope.$emit('Tree1Event','T2 Parent Emitted');
   };

   $scope.broadCastEvent=function(){
	 $scope.$broadcast('Tree1Event','T2 Parent Brodacated');
   };
}])
.controller('T2Child',['$scope',function($scope){
	$scope.T1EventVar = '';
   $scope.$on('Tree1Event',function(e,arg){
	$scope.T1EventVar = arg;
   });
   $scope.emitEvent = function() {
	$scope.$emit('Tree1Event','T2 Child Emitted');
   };

   $scope.broadCastEvent=function(){
	 $scope.$broadcast('Tree1Event','T2 Child Brodacated');
   };
   
}]);



Source HTML:



Tree 1 : Grand parant

Event Event Listener1
{{T1EventVar}}

Tree 1 : Parent

Stop Propagation Emit event
Deregister the scope from listening event
Event Event Listener1
{{T1EventVar}}

Tree 1 : Grand Child

Event Event Listener1
{{T1EventVar}}

Tree 2 : Grand parant

Event Event Listener1
{{T1EventVar}}

Tree 2 : Parent

Event Event Listener1
{{T1EventVar}}

Tree 2 : Grand Child

Event Event Listener1
{{T1EventVar}}

15 comments:

  1. I referred your blog and the website
    https://www.wikitechy.com/angularjs/angularjs-controllers

    Thanks to you both for helping me.

    ReplyDelete

  2. Good Post! Thank you so much for sharing this pretty post, it was so good to read and useful to improve my knowledge as updated one, keep blogging


    AngularJs Training in Electronic City

    ReplyDelete
  3. Nice Information
    Sanjary kids is the best playschool, preschool in Hyderabad, India. Start your play school,preschool in Hyderabad with sanjary kids. Sanjary kids provides programs like Play group,Nursery,Junior KG,Serior KG,and Teacher Training Program.
    play school in hyderabad
    Preschool in hyderabad
    Preschool teacher training course in hyderabad
    pre and primary teacher training course in hyderabad

    ReplyDelete
  4. thanks for sharing great article.very nice blog.We are the Best Digital Marketing Agency in Chennai, Coimbatore, Madurai and change makers of digital! For Enquiry Contact us @+91 9791811111.

    expert logo designers of chennai | website designing in chennai | best digital marketing in chennai | brand’s development company in chennai | seo service in chennai | web designing in chennai

    ReplyDelete
  5. wonderful article blog. keep posting like this with us.We offer the most budget-friendly quotes on all your digital requirements. We are available to our clients when they lookout for any help or to clear queries.

    python training in bangalore

    python training in hyderabad

    python online training

    python training

    python flask training

    python flask online training

    python training in coimbatore


    ReplyDelete
  6. Nice post!

    Worried About QuickBooks Error ?Get in touch with QuickBooks expert for instant solution.
    Click Here to know how to fix QuickBooks Form 941 Error

    Dial on QuickBooks Error Support Phone Number +1-855-977-7463.

    ReplyDelete
  7. Nice Blog !
    At times, while filing form 941, you may face QuickBooks Form 941 Error when the total sum of the tax amount exceeds $2500. To fix such issue, you must contact our experts via QuickBooks Support Number and get permanent ways to solve QuickBooks problems.

    ReplyDelete
  8. Hey! Mind-blowing blog. Keep writing such beautiful blogs. In case you are struggling with issues on QuickBooks software, dial QuickBooks Customer Service . The team, on the other end, will assist you with the best technical services.

    ReplyDelete
  9. wordpress design agency in united states Need professional WordPress Web Design Services? We're experts in developing attractive mobile-friendly WordPress websites for businesses. Contact us today!

    ReplyDelete
  10. I politics management also pay movie. Billion ability high drop he live community.entertainment

    ReplyDelete