简体   繁体   中英

angularJs call function from different controllers

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.

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, ie $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, eg

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

如果要在同级控制器之间以及从父级控制器到子级控制器之间进行通信,则必须使用$ scope。$ broadcast,但如果要从子级到父级进行通信,则必须使用$ scope。$ emit

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM