javascript - Why do events from provider not $emit to $rootScope? - Stack Overflow

To keep things de-coupled in my AngularJS app, I've got a single validationService that different

To keep things de-coupled in my AngularJS app, I've got a single validationService that different controllers may call to perform the validation. As it is, the validate() method in a given controller should just $emit an event (request:validate, for example) which the service will listen for -- but it does not appear that $rootScope ever receives the emitted event. For example:

angular.module('mine').controller('CommitController', [
    '$scope',
    function($scope) {
        $scope.validate = function() {
            $scope.$emit('request:validate');
        };
    }
]);
angular.module('mine.services').factory('validationService', [
    '$rootScope',
    function($rootScope) {
        $rootScope.$on('request:validate', function(e) {
            console.log('received the request:validate event - go ahead with validation');
        });
    }
]);

But the $on('request:validate') never fires from $rootScope. Does $rootScope not receive events emitted from child scopes? Is there some quirk in how $rootScope listens to events?

Is there a "more Angular" approach to this? Should the controllers simply call validationService directly? Should the events $broadcast from $rootScope to begin with?

To keep things de-coupled in my AngularJS app, I've got a single validationService that different controllers may call to perform the validation. As it is, the validate() method in a given controller should just $emit an event (request:validate, for example) which the service will listen for -- but it does not appear that $rootScope ever receives the emitted event. For example:

angular.module('mine').controller('CommitController', [
    '$scope',
    function($scope) {
        $scope.validate = function() {
            $scope.$emit('request:validate');
        };
    }
]);
angular.module('mine.services').factory('validationService', [
    '$rootScope',
    function($rootScope) {
        $rootScope.$on('request:validate', function(e) {
            console.log('received the request:validate event - go ahead with validation');
        });
    }
]);

But the $on('request:validate') never fires from $rootScope. Does $rootScope not receive events emitted from child scopes? Is there some quirk in how $rootScope listens to events?

Is there a "more Angular" approach to this? Should the controllers simply call validationService directly? Should the events $broadcast from $rootScope to begin with?

Share Improve this question edited Nov 11, 2015 at 17:59 CLo 3,7304 gold badges28 silver badges45 bronze badges asked Aug 1, 2013 at 15:19 founddramafounddrama 2,4111 gold badge23 silver badges31 bronze badges 5
  • Why not just use the validation service directly? why do you have to listen? – Fresheyeball Commented Aug 1, 2013 at 18:04
  • @Fresheyeball - That is an excellent question and is certainly another approach I could take. Calling methods on the service directly may prove to be more appropriate, but I was also puzzled by why the events didn't appear to be making it to the $rootScope. – founddrama Commented Aug 1, 2013 at 18:09
  • I understand and your question is valid and useful, it just that in this case it seems indicative of a structural design flaw. For services, direct usage of a method seems to be the preferred methodology. $emit is more prevalent used inside directives, with the listeners taking place in controllers. Just an FYI. – Fresheyeball Commented Aug 1, 2013 at 18:12
  • @Fresheyeball - that makes sense -- but given what you're describing, why not call the services directly from the directives? Unless I'm misinterpreting and what you mean is that you don't want to call service code in the first place and thus $emit is used to "call" methods in the controller from the directives. – founddrama Commented Aug 1, 2013 at 19:11
  • I would call the service directly from the directive. IMHO the purpose of $emit and $on is for directive -> controller, and global messaging. Services should always get called directly. – Fresheyeball Commented Aug 1, 2013 at 20:16
Add a ment  | 

1 Answer 1

Reset to default 6

You are not instantiating validationService therefore the listener does not get attached. Include it in the module and inject it to the controller.

angular.module('mine',["mine.services"]).controller('CommitController', [
    '$scope', "validationService",
    function($scope, vs) {
        $scope.validate = function() {
            $scope.$emit('request:validate');
        };
    }
]);
angular.module('mine.services',[]).factory('validationService', [
    '$rootScope',
    function($rootScope) {
        $rootScope.$on('request:validate', function(e) {
            console.log('received the request:validate event -'+
                         'go ahead with validation');
        });
    }
]);

If you don't want to inject the service into controller, you do the binding in module's run method

angular.module("mine", ["mine.services"]).run(function(validationService){});

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742397765a4436290.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信