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}}

11 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. Hiiii....Thanks for sharing Great info...Nice post...Keep move on...
    Angular JS Training in Hyderabad

    ReplyDelete
  4. Good Information
    "Pressure Vessel Design Course is one of the courses offered by Sanjary Academy in Hyderabad. We have offer professional
    Engineering Course like Piping Design Course,QA / QC Course,document Controller course,pressure Vessel Design Course,
    Welding Inspector Course, Quality Management Course, #Safety officer course."
    Piping Design Course
    Piping Design Course in India­
    Piping Design Course in Hyderabad
    QA / QC Course
    QA / QC Course in india
    QA / QC Course in Hyderabad
    Document Controller course
    Pressure Vessel Design Course
    Welding Inspector Course
    Quality Management Course
    Quality Management Course in india
    Safety officer course

    ReplyDelete
  5. Thanks for sharing
    We are the best piping design course in Hyderabad, India. Sanjary academy Offers Piping Design Course and Best Piping Design Training Institute in Hyderabad. Piping Design Institute in India Piping Design Engineering.
    Piping Design Course
    Piping Design Course in india
    Piping Design Course in hyderabad

    ReplyDelete
  6. 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
  7. Thanks for sharing information
    "Pressure Vessel Design Course is one of the courses offered by Sanjary Academy in Hyderabad. We have offer professional
    Engineering Course like Piping Design Course,QA / QC Course,document Controller course,pressure Vessel Design Course,
    Welding Inspector Course, Quality Management Course, #Safety officer course."
    Piping Design Course
    Piping Design Course in India­
    Piping Design Course in Hyderabad
    Welding Inspector Course
    Quality Management Course
    Quality Management Course in india
    Safety officer course

    ReplyDelete
  8. Thanks for Sharing This Article.It is very so much valuable content. I hope these Commenting lists will help to my website
    angularjs online training
    top angularjs online training
    best angularjs online training

    ReplyDelete