Calling a method in a controller defined in a directive from a javascript function

本小妞迷上赌 提交于 2019-12-13 00:45:50

问题


I am looking for a way to call a method in a controller defined in a directive from a global function. I was able to successfully do this defining the controller in the module and declaring the controller using ng-controller in a normal html element. Then I get the controller and the scope from the javascript function like this:

function signinCallback(authResult) {
    var googleLoginControllerElement = document.getElementById('googlelogin');
    var ctrlScope = angular.element(googleLoginControllerElement).scope();
    var controller = angular.element(googleLoginControllerElement).controller();

    ctrlScope.$apply(function() {
        controller.signinCallBack(authResult);
    });
}

but when I moved the definition of the controller to the definition of a directive I was not able to find a way to do this (new code after moving the controller definition to a directive):

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

googleLogin.directive('googleLogin', function() {
    return {

    restrict: 'E',
    controller: function() {
    // Initialize google login api
    (function() {
        var po = document.createElement('script'); 
        po.type = 'text/javascript';
        po.async = true;
        po.src = 'https://apis.google.com/js/client:plusone.js';
        var s = document.getElementsByTagName('script')[0];
        s.parentNode.insertBefore(po, s);
     })();

         /*
         * 1: not logged in.
         * 2: logged in.
         * 3: login failed.
         * 4: logout failed.
         */
         this.state = 1;

         this.signinCallBack = function(authResult) {
         if (authResult['status']['signed_in']) {
             console.log('authResult: ' + JSON.stringify(authResult));
             this.state = 2;
         } else if (authResult.error === "user_signed_out") {
             console.log('Sign-in state: ' + authResult['error']);
                 this.state = 1;
         }
        };

        this.logout = function() {
            try {
                gapi.auth.signOut();
                this.state = 1;
             } catch(e) {
                 this.state = 4;
             }
        };

        this.isLoggedIn = function() {
            return this.state == 2;
        };
    },
    controllerAs: 'googleLoginCtrl',
    templateUrl: '../templates/google_login.html'
};
});

In my html I use the directive like this:

<google-login></google-login>

Thanks!


回答1:


You will need to specify the scope which your directive must use.

Refer this doc : https://docs.angularjs.org/guide/directive

**Edit : **

I gave an id to your element so that I can get access to it.

<google-login id="mybtn"></google-login>

& Changed your global function as .

function signinCallback(authResult) {
//  alert('I came here also inside callback global');

  var googleLoginControllerElement = document.getElementById('mybtn');
  var ctrlScope = angular.element(googleLoginControllerElement).scope();

 ctrlScope.$apply(function() {
      ctrlScope.googleLoginCtrl.signinCallBack(authResult);
     });

  //      ctrlScope.googleLoginCtrl.signinCallBack(authResult);
  //alert('I came here also inside callback global end');

}

I was trying ctrlScope.controller but oversaw that a name was given to it.




回答2:


You can try something like this (i'm not sure if it will work, let me know):

window.globalSigninCallBack = this.signinCallBack;

inside of your directive:

googleLogin.directive('googleLogin', function() {
    return {

    restrict: 'E',
    controller: function() {
    // Initialize google login api
    (function() {
        var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
        po.src = 'https://apis.google.com/js/client:plusone.js';
        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
        })();

         /*
         * 1: not logged in.
         * 2: logged in.
         * 3: login failed.
         * 4: logout failed.
         */
         this.state = 1;

         this.signinCallBack = function(authResult) {
         if (authResult['status']['signed_in']) {
             console.log('authResult: ' + JSON.stringify(authResult));
             this.state = 2;
         } else if (authResult.error === "user_signed_out") {
             console.log('Sign-in state: ' + authResult['error']);
                 this.state = 1;
         }
        };

        window.globalSigninCallBack = this.signinCallBack;

        this.logout = function() {
            try {
                gapi.auth.signOut();
                this.state = 1;
             } catch(e) {
                 this.state = 4;
             }
        };

        this.isLoggedIn = function() {
            return this.state == 2;
        };
    },
    controllerAs: 'googleLoginCtrl',
    templateUrl: '../templates/google_login.html'
};
});

then later in the code call:

window.globalSigninCallBack(authResult);

but this is very hacky workaround and i would never use this in my code:)



来源:https://stackoverflow.com/questions/26018812/calling-a-method-in-a-controller-defined-in-a-directive-from-a-javascript-functi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!