问题
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