我有一个应用程序,在应用程序内部是注册和登录表单。
使用注册表单,当用户创建帐户时,他们会自动登录。
使用登录表单,用户也可以登录(显然)。
我有两个控制器:一个用于注册表单,另一个用于登录表单。我希望他们能够共享服务'logIn',因为这两种形式的用户最终都会登录。
到目前为止一直在努力。我唯一的问题是登录表单异步检查用户对数据库的登录凭据,如果处理此请求的PHP脚本返回说没有匹配,则angular更新错误消息的模型,如下所示给用户。当'logIn'服务不用作服务时,这种方法完全正常,但只是复制到两个控制器中。以下是'SignupCtrl'的外观:
.controller('SignupCtrl',['$scope','$http',function($scope,$http) {
$scope.error = false;
$scope.logIn = function() {
var data = // user's login credentials
$http({
// send credentials to server, ask if there's a match
})
.success(function(data) {
if(data.match === false) {
$scope.error = true;
} else {
// start session, redirect to new page, etc.
}
})
}
}]);
然后,在模板内:
<div ng-show="error">Oops! That email/password doesn't exist.</div>
这很好用;但正如我所说,不是'logIn'函数用作服务时。这是因为我无法弄清楚如何在服务中更新$scope.error
。
我尝试过使用$rootScope
(这不起作用):
.service('logIn',[/* injections */, '$rootScope', function(/* injections */, $rootScope) {
return function(email, password) {
// all the same code as before
if(data.match === false) {
$rootScope.error = true; // this does nothing
}
}
}]);
// in the controller (the service is injected in as 'logIn')
$scope.logIn = logIn;
然后,在模板中:
<button ng-click="logIn(user.email, user.password)">Login</button>
用户可以使用该服务正常登录。问题只是用服务更新$scope.error
变量。
也许如果我能以某种方式做到这一点,它会起作用:
<button ng-click="logIn(user.email, user.password, $scope)">Login</button>
然后在服务中:
return function(email, password, scope) {
// etc.
if(data.match === false) {
scope.error = true;
}
}
有什么想法?谢谢。
只是为了澄清,根据我对services
的理解,它们似乎取代了人们通常如何声明一个全局函数,或者仅仅是模块内部的整体函数,以避免重复自己。例如:
(function() {
function globalFunction() {
//etc.
}
$('.thing').click(globalFunction);
$('.otherThing').click(globalFunction);
}());
可能有一个更好的例子,但我认为这个想法是明确的。
这个概念是否与在角度内使用服务的方式类似?如果没有,是否有更好的方式让我去做我正在尝试做的事情而不使用服务?
答案 0 :(得分:2)
您可以将$rootScope
传递给服务,但污染您的$rootScope
通常不是一个好主意,但是在这个特殊情况下您的问题是没有强制摘要因此你的控制器$scope
没有意识到这种变化。在您发布的代码中,如果将$rootScope.error
包裹在$rootScope.$apply()
内,则可以正常工作。但回调更清晰。
我建议你将回调传递给service方法,并在回调中设置你的范围变量:
login:function(email,password,callback){
$http({
// send credentials to server, ask if there's a match
})
.success(function(data) {
callback(data.match);
})
}
并在您的控制器中:
$scope.logIn = function() {
loginServcie.login($scope.email,$scope.password,function(dataIsMatched){
//you now have the result of call, and dataIsMatched is true or false
$scope.error = !dataIsMatched;
})
}