简体   繁体   中英

Call from Plain JavaScript to Angular Service to Controller

I am using $rootScope.$emit() for raising events from service to controller.

It is working fine when emitting from the instance of service that is referenced in controller but $rootScope.$on is not getting called when emitting from the instance of service I got from angular injector in plain javascript .

Following is my code

Plain JavaScript

    var msgHandlerJS = function () {
    var injector = angular.injector(['ng', 'services']);
    var aMsgHandlerService = injector.get('msgHandlerService');

    aMsgHandlerService.TestScopeWatch();
}

Calling the above when dom is ready :

angular.element(document).ready(function () {    
    msgHandlerJS();
});

Service

(function (module) {    

    var msgHandlerService = function ($rootScope, $http, $q, $timeout) {  
        var TestScopeWatch = function () {
            $http.get('~/test.json').then(function (result) {
                EmailPacket = result.data.Packet;

                $rootScope.$emit("EmailPacketChanged", EmailPacket);     
            });
        };

        return {
            //making public
            TestScopeWatch:TestScopeWatch,
        };
    };

    module.factory("msgHandlerService", ["$rootScope","$http", "$q","$timeout", msgHandlerService]);

}(angular.module("services")));

Controller

(function (module) {   
    function testController($rootScope,$scope, msgHandlerService) {
        $rootScope.$on("EmailPacketChanged", function(event,data){
            alert('Here I am');
        };
    };

    module.controller("testController", ["$rootScope","$scope", "msgHandlerService",  testController]);    

}(angular.module('app')));

You need to get the proper injector of the application, angular.injector creates a new injector, it has nothing to do with the injector that bootstrapped your app. So the instance of the service (yourService, rootScope inside it) you get from that injector is different instance than what is in the app. You should instead use the getter .injector() from the rootElement of the application.

ie if you have an ng-app or manually bootstrapping, get the injector out of that element. Example:

 var injector = angular.element(document.querySelector('[ng-app]')).injector();

If your app root is document ( html ) then get injector from the document ie :

var injector = angular.element(document).injector()

Also if you want any scope bindings to reflect you also need to invoke a digest cycle (alert will work fine ofcourse):

var msgHandlerJS = function() {
   var injector = angular.element(document).injector();
   var aMsgHandlerService = injector.get('msgHandlerService');
   var $rootScope = injector.get('$rootScope');
   aMsgHandlerService.TestScopeWatch();
   $rootScope.$digest();
}

 (function(module) { var msgHandlerService = function($rootScope, $http, $q, $timeout) { var TestScopeWatch = function() { //$http.get('~/test.json').then(function(result) { // EmailPacket = result.data.Packet; $rootScope.$emit("EmailPacketChanged", {}); // }); }; return { //making public TestScopeWatch: TestScopeWatch, }; }; module.factory("msgHandlerService", ["$rootScope", "$http", "$q", "$timeout", msgHandlerService]); }(angular.module("services", []))); (function(module) { function testController($rootScope, $scope, msgHandlerService) { $rootScope.$on("EmailPacketChanged", function(event, data) { $scope.got = "got the message!!"; }); } module.controller("testController", ["$rootScope", "$scope", "msgHandlerService", testController]); }(angular.module('app', ['services']))); var msgHandlerJS = function() { var injector = angular.element(document.querySelector('[ng-app]')).injector(); var aMsgHandlerService = injector.get('msgHandlerService'); var $rootScope = injector.get('$rootScope'); aMsgHandlerService.TestScopeWatch(); $rootScope.$digest(); } angular.element(document).ready(function() { msgHandlerJS(); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <div class="test" ng-app="app" ng-controller="testController"> {{got}} </div> 

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