Can one AngularJS controller call another? Can one AngularJS controller call another? javascript javascript

Can one AngularJS controller call another?


There are multiple ways how to communicate between controllers.

The best one is probably sharing a service:

function FirstController(someDataService) {  // use the data service, bind to template...  // or call methods on someDataService to send a request to server}function SecondController(someDataService) {  // has a reference to the same instance of the service  // so if the service updates state for example, this controller knows about it}

Another way is emitting an event on scope:

function FirstController($scope) {  $scope.$on('someEvent', function(event, args) {});  // another controller or even directive}function SecondController($scope) {  $scope.$emit('someEvent', args);}

In both cases, you can communicate with any directive as well.


See this fiddle: http://jsfiddle.net/simpulton/XqDxG/

Also watch the following video: Communicating Between Controllers

Html:

<div ng-controller="ControllerZero">  <input ng-model="message" >  <button ng-click="handleClick(message);">LOG</button></div><div ng-controller="ControllerOne">  <input ng-model="message" ></div><div ng-controller="ControllerTwo">  <input ng-model="message" ></div>

javascript:

var myModule = angular.module('myModule', []);myModule.factory('mySharedService', function($rootScope) {  var sharedService = {};  sharedService.message = '';  sharedService.prepForBroadcast = function(msg) {    this.message = msg;    this.broadcastItem();  };  sharedService.broadcastItem = function() {    $rootScope.$broadcast('handleBroadcast');  };  return sharedService;});function ControllerZero($scope, sharedService) {  $scope.handleClick = function(msg) {    sharedService.prepForBroadcast(msg);  };  $scope.$on('handleBroadcast', function() {    $scope.message = sharedService.message;  });        }function ControllerOne($scope, sharedService) {  $scope.$on('handleBroadcast', function() {    $scope.message = 'ONE: ' + sharedService.message;  });        }function ControllerTwo($scope, sharedService) {  $scope.$on('handleBroadcast', function() {    $scope.message = 'TWO: ' + sharedService.message;  });}ControllerZero.$inject = ['$scope', 'mySharedService'];        ControllerOne.$inject = ['$scope', 'mySharedService'];ControllerTwo.$inject = ['$scope', 'mySharedService'];


If you want to call one controller into another there are four methods available

  1. $rootScope.$emit() and $rootScope.$broadcast()
  2. If Second controller is child ,you can use Parent child communication .
  3. Use Services
  4. Kind of hack - with the help of angular.element()

1. $rootScope.$emit() and $rootScope.$broadcast()

Controller and its scope can get destroyed,but the $rootScope remains across the application, that's why we are taking $rootScope because $rootScope is parent of all scopes .

If you are performing communication from parent to child and even child wants to communicate with its siblings, you can use $broadcast

If you are performing communication from child to parent ,no siblings invovled then you can use $rootScope.$emit

HTML

<body ng-app="myApp">    <div ng-controller="ParentCtrl" class="ng-scope">      // ParentCtrl      <div ng-controller="Sibling1" class="ng-scope">        // Sibling first controller      </div>      <div ng-controller="Sibling2" class="ng-scope">        // Sibling Second controller        <div ng-controller="Child" class="ng-scope">          // Child controller        </div>      </div>    </div></body>

Angularjs Code

 var app =  angular.module('myApp',[]);//We will use it throughout the example     app.controller('Child', function($rootScope) {      $rootScope.$emit('childEmit', 'Child calling parent');      $rootScope.$broadcast('siblingAndParent');    });app.controller('Sibling1', function($rootScope) {  $rootScope.$on('childEmit', function(event, data) {    console.log(data + ' Inside Sibling one');  });  $rootScope.$on('siblingAndParent', function(event, data) {    console.log('broadcast from child in parent');  });});app.controller('Sibling2', function($rootScope) {  $rootScope.$on('childEmit', function(event, data) {    console.log(data + ' Inside Sibling two');  });  $rootScope.$on('siblingAndParent', function(event, data) {    console.log('broadcast from child in parent');  });});app.controller('ParentCtrl', function($rootScope) {  $rootScope.$on('childEmit', function(event, data) {    console.log(data + ' Inside parent controller');  });  $rootScope.$on('siblingAndParent', function(event, data) {    console.log('broadcast from child in parent');  });});

In above code console of $emit 'childEmit' will not call inside child siblings and It will call inside only parent, where $broadcast get called inside siblings and parent as well.This is the place where performance come into a action.$emit is preferrable, if you are using child to parent communication because it skips some dirty checks.

2. If Second controller is child, you can use Child Parent communication

Its one of the best method, If you want to do child parent communication where child wants to communicate with immediate parent then it would not need any kind $broadcast or $emit but if you want to do communication from parent to child then you have to use either service or $broadcast

For example HTML:-

<div ng-controller="ParentCtrl"> <div ng-controller="ChildCtrl"> </div></div>

Angularjs

 app.controller('ParentCtrl', function($scope) {   $scope.value='Its parent';      });  app.controller('ChildCtrl', function($scope) {   console.log($scope.value);  });

Whenever you are using child to parent communication, Angularjs will search for a variable inside child, If it is not present inside then it will choose to see the values inside parent controller.

3.Use Services

AngularJS supports the concepts of "Seperation of Concerns" using services architecture. Services are javascript functions and are responsible to do a specific tasks only.This makes them an individual entity which is maintainable and testable.Services used to inject using Dependency Injection mecahnism of Angularjs.

Angularjs code:

app.service('communicate',function(){  this.communicateValue='Hello';});app.controller('ParentCtrl',function(communicate){//Dependency Injection  console.log(communicate.communicateValue+" Parent World");});app.controller('ChildCtrl',function(communicate){//Dependency Injection  console.log(communicate.communicateValue+" Child World");});

It will give output Hello Child World and Hello Parent World . According to Angular docs of services Singletons – Each component dependent on a service gets a reference to the single instance generated by the service factory.

4.Kind of hack - with the help of angular.element()

This method gets scope() from the element by its Id / unique class.angular.element() method returns element and scope() gives $scope variable of another variable using $scope variable of one controller inside another is not a good practice.

HTML:-

<div id='parent' ng-controller='ParentCtrl'>{{varParent}} <span ng-click='getValueFromChild()'>Click to get ValueFormChild</span> <div id='child' ng-controller='childCtrl'>{{varChild}}   <span ng-click='getValueFromParent()'>Click to get ValueFormParent </span> </div></div>

Angularjs:-

app.controller('ParentCtrl',function($scope){ $scope.varParent="Hello Parent";  $scope.getValueFromChild=function(){  var childScope=angular.element('#child').scope();  console.log(childScope.varChild);  }});app.controller('ChildCtrl',function($scope){ $scope.varChild="Hello Child";  $scope.getValueFromParent=function(){  var parentScope=angular.element('#parent').scope();  console.log(parentScope.varParent);  }}); 

In above code controllers are showing their own value on Html and when you will click on text you will get values in console accordingly.If you click on parent controllers span, browser will console value of child and viceversa.