2

I was wondering if is it possible to call one controller's function from another controller. This way i tried but failed:

<div ng-app="MyApp">
    <div ng-controller="Ctrl1">
        <button ng-click="func1()">func1</button>
    </div>
    <br>
    <div ng-controller="Ctrl2">
        <button ng-click="func2()">func2</button>
    </div>
</div>

var app = angular.module('MyApp', []);

app.controller('Ctrl1', function($scope) {

  $scope.func1 = function() {
    alert('Ctrl1 and func1')
  }

    $scope.$on("MyFunction", function () {
        alert('Ctrl1 MyFunction')
    });
});

app.controller('Ctrl2', function($scope) {

  $scope.func2 = function() {
    alert('Ctrl2 and func2')
    $scope.$emit("MyFunction");
  }

});

when func2 is calling then i used $scope.$emit("MyFunction"); to call Ctrl1 MyFunction but it does not worked. so is it not possible ?

please put some light here.

Mistalis
  • 17,793
  • 13
  • 73
  • 97
Monojit Sarkar
  • 2,353
  • 8
  • 43
  • 94

3 Answers3

2

when you wanted to communicate with sibiling controllers you have to catch the event($on) using rootScope. use this

$rootScope.$on("MyFunction", function () {
            alert('Ctrl1 MyFunction')
});

Demo

var app = angular.module('MyApp', []);

app.controller('Ctrl1', function($scope,$rootScope) {

  $scope.func1 = function() {
    alert('Ctrl1 and func1')
  }

    $rootScope.$on("MyFunction", function () {
        alert('Ctrl1 MyFunction')
    });
});

app.controller('Ctrl2', function($scope) {

  $scope.func2 = function() {
    alert('Ctrl2 and func2')
    $scope.$emit("MyFunction");
  }

});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="MyApp">
    <div ng-controller="Ctrl1">
        <button ng-click="func1()">func1</button>
    </div>
    <br>
    <div ng-controller="Ctrl2">
        <button ng-click="func2()">func2</button>
    </div>
</div>
Sachila Ranawaka
  • 39,756
  • 7
  • 56
  • 80
  • 1
    yes it worked but you said another approach like "even better you could declare your functions as a service and use angulars dependency injection to inject your service into your controller" so would show this approach too in second example. this is just a request because i am new in angular – Monojit Sarkar Jun 07 '17 at 13:58
  • it is not suitable for this approach. since you want to go to a controller function from another controller then this approach is okay – Sachila Ranawaka Jun 07 '17 at 14:02
2

As you asked here for a solution using a service, here is an example.

I created 2 controllers (FirstCtrl, SecondCtrl) that use a single service (Data).

Note that the function alertName() is defined on the service, and each controller can use it because the service is injected in each controller.

var myApp = angular.module('myApp', []);

myApp.service('Data', function() {
  var name = 'Mistalis';
  return {
    alertName: function() {
      alert(name);
    }
  };
});

myApp.controller('FirstCtrl', function($scope, Data) {
  $scope.showName = function() {
    Data.alertName();
  }
});

myApp.controller('SecondCtrl', function($scope, Data) {
  $scope.showName = function() {
    Data.alertName();
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="myApp">
  <div ng-controller="FirstCtrl">
    Controller 1<br/>
    <button ng-click="showName()">Show name from service</button>
  </div>
  <hr>
  <div ng-controller="SecondCtrl">
    Controller 2<br/>
    <button ng-click="showName()">Show name from service</button>
  </div>
</div>
Mistalis
  • 17,793
  • 13
  • 73
  • 97
  • I have seen your code but it just show how to controller can call a common function but how this approach can be used by 2 controllers to share data in each other or share data in each other ? – Monojit Sarkar Jun 07 '17 at 17:19
  • @MonojitSarkar Like in [**this Fiddle**](http://jsfiddle.net/Mistalis/q9ctyL6j/1/)? – Mistalis Jun 08 '17 at 07:16
2

Use $rootScope.$broadcast:

app.controller('Ctrl1', function($scope) {

  $scope.func1 = function() {
    alert('Ctrl1 and func1')
  }

    $scope.$on("MyFunction", function () {
        alert('Ctrl1 MyFunction')
    });
});

app.controller('Ctrl2', function($scope, $rootScope) {

  $scope.func2 = function() {
    alert('Ctrl2 and func2')
    //$scope.$emit("MyFunction");
    //USE rootScope
    $rootScope.$broadcast("MyFunction");
  }

});

Best practice: To avoid memory leaks, avoid using $on listeners on $rootScope. Listeners on $scope will be properly destroyed automatically when controllers are removed.

For more information on the AngularJS event bus, see

georgeawg
  • 48,608
  • 13
  • 72
  • 95