从javascript函数调用指令中定义的控制器中的方法
我正在寻找一种方法,在全局函数的指令中定义的控制器中调用方法。我能够成功地在模块中定义控制器,并在普通html元素中使用ng控制器声明控制器。然后我从javascript函数中获取控制器和作用域,如下所示:从javascript函数调用指令中定义的控制器中的方法,javascript,angularjs,Javascript,Angularjs,我正在寻找一种方法,在全局函数的指令中定义的控制器中调用方法。我能够成功地在模块中定义控制器,并在普通html元素中使用ng控制器声明控制器。然后我从javascript函数中获取控制器和作用域,如下所示: function signinCallback(authResult) { var googleLoginControllerElement = document.getElementById('googlelogin'); var ctrlScope = angular.e
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);
});
}
<google-login></google-login>
但当我将控制器的定义移动到指令的定义时,我无法找到这样做的方法(将控制器定义移动到指令后的新代码):
在我的html中,我使用如下指令:
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);
});
}
<google-login></google-login>
谢谢 您可以尝试类似的方法(我不确定是否有效,请告诉我): 在您的指令中:
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'
};
});
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'
};
});
然后在稍后的代码调用中:
window.globalSigninCallBack(authResult);
但这是一种非常粗糙的解决方法,我永远不会在代码中使用它:)您需要指定指令必须使用的范围 请参阅本文件: **编辑:** 我给了你的元素一个id以便我可以访问它
<google-login id="mybtn"></google-login>
我正在尝试ctrlScope.controller,但发现它有一个名称。为什么要从全局函数调用该函数?googleLoginCtrl在哪里?@Joao,全局函数由oauth登录工作流调用。从那里,我想将控制流传递给angular模块,提供宣誓验证的结果(代码中的authResult变量),以便angular模块跟踪登录状态。@Sergey,这是控制器的别名。我使用它从我的模板(google_login.html)中引用它。我没有包含模板中的代码,因为它与当前的问题无关,但如果它能帮助您更好地理解我的意图,我可以这样做。@Cristobal您可以(应该?)吗将您的登录工作流放在angular指令中,然后它将全部放在angular世界中。在您提供的链接中,我找不到任何可用于解决我的问题的内容。你认为你能用代码提供一个例子吗?你能创建一个plunkr或js提琴吗?想法是在将对控制器的调用包装到传递给ctrlScope的函数中之后,从google_login.jsworked中的全局函数signinCallback(authResult)调用GoogleLogin模块中的signinCallback(authResult)方法。如下所示:$apply():ctrlScope。$apply(function(){ctrlScope.googleLoginCtrl.signinCallback(authResult); }); 请参阅我问题中的第一段代码。在我接受正确答案之前,请使用此修复编辑答案。@Cristobal。请检查编辑。(但原来的那把在你的小提琴里起作用。)我试了一下。直接调用window不起作用。您必须导入$window服务并调用$window.globalSigninCallBack=this.signinCallBack;这种方法对我不起作用。我使用调试器逐步完成了说明,一切看起来都很好,但是绑定没有得到更新。我试着在不同的地方调用$apply,但它没有定义。@Cristobal我在plunker中设置了一个小示例,我也成功了,但我无法更改控制器的状态。例如,根据您的示例,我无法更改$scope.name的值并在页面中看到效果。