angularJs call function from different controllers

527 views Asked by At

We are trying to develop an app using phonegap onsen and angularJS.

I am trying to call a function from a different controllers. I have seen alot of documentation on how to do this like this

But for certain reason it doesn't work for me. Here is my code so far.

module.run(function ($rootScope) {
    $rootScope.$on('some-event-here', function (event, data) {
        console.log('1');
        $rootScope.$emit('show-dialog-of-some-event', data);

        //I also tried
        //$rootScope.$broadcast('show-dialog-of-some-event', data); 
    });
});

module.controller('controller1', ['$scope', '$http',  function($scope, $http) {
    $scope.proceed = function() {
        console.log('0');
        $scope.$emit('some-event-here', {});
    }
}]);

module.controller('controller2', ['$scope', '$http',  function($scope, $http) {
    $scope.$on('show-dialog-of-some-event', function (event, data) {
        console.log('2');
        ons.createDialog('some-dialog.html').then(function(dialog) {                        
            //some code here
        });
    });
}]);

It show on the console '0' and '1' but it doesn't show '2'.

This could be an easy problem but I can't seem to find the problem with my code.

Thanks in advance.

4

There are 4 answers

3
Shubham Nigam On

If you are communicating between sibling controllers and from parent controller to child controller you have to use $scope.$broadcast but If you want to communication from child to parent you have to use $scope.$emit

0
user4168664 On

I think what may be occurring is that you declare an event handler for the event 'show-dialog-of-some-event' in the local scope of controller2, i.e. $scope. You emit an event in the $rootScope. Emitted events bubble up not down, so the event 'show-dialog-of-some-event' does not "bubble down" from the $rootScope to $scope. You may want to define the event handler for 'show-dialog-of-some-event' on the root scope instead, e.g.

    $rootScope.$on('show-dialog-of-some-event', function(e,d) {});
6
Robin-Hoodie On

2 things are wrong with your code:

1: $broadcast bubbles events down the scope hierarchy, $emit is for bubbling them up the scope hierarchy, instead use this:

$rootScope.$broadcast('show-dialog-of-some-event', data);

For more info see this answer: $rootScope.$broadcast vs. $scope.$emit

2: the run function of your module will be executed before your controller will attach an event handler for this event, therefore the event will have already passed by the time you configure an event handler in your controller:

Again, see this answer AngularJS app.run() documentation?

So the solution to your answer is:

  • change the $emit to $broadcast
  • move the $broadcast call later into the lifecycle so the controller will have attached its listener

Here's a plunkr where I'm calling $broadcast later in the lifecycle (in this case when the window loads):

http://plnkr.co/edit/W7efiKqIlu4va4AcBTbG

0
Icycool On

If you don't need to process anything on rootscope you can just inject $rootScope into controller

module.controller('controller1', ['$scope', '$http', '$rootScope', function($scope, $http, $rootScope) {
    $scope.proceed = function() {
        console.log('0');
        $rootScope.$boardcast('some-event-here', {});
    }
}]);

module.controller('controller2', ['$scope', '$http',  function($scope, $http) {
    $scope.$on('some-event-here', function (event, data) {
        console.log('2');
    });
}]);

It's less clean than using a service but you can use this pattern if it's not too often.