我创建了一个使用$ http发布登录数据并获取身份验证令牌的服务,但每当我将其注入控制器时,它就会中断(看起来像html看不到它)。当我删除服务注入,或者使用$ resource注入一个服务注入时,一切正常。 这是服务的代码:
MyApp.service('LoginSrv', ['$http', function User($http) {
var userData = {
isAuthenticated: false,
username: '',
bearerToken: '',
expirationDate: null,
};
function setHttpAuthHeader() {
$http.defaults.headers.common.Authorization = 'Bearer ' + userData.bearerToken;
}
this.getUserData = function(){
return userData;
};
this.authenticate = function(username, password, successCallback, errorCallback) {
var config = {
method: 'POST',
url: '/accounts/login',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
data: 'grant_type=password&username=' + username + '&password=' + password,
};
$http(config)
.success(function(data) {
userData.isAuthenticated = true;
userData.username = data.userName;
userData.bearerToken = data.access_token;
userData.expirationDate = new Date(data['.expires']);
setHttpAuthHeader();
if (typeof successCallback === 'function') {
successCallback();
}
})
.error(function(data) {
if (typeof errorCallback === 'function') {
if (data.error_description) {
errorCallback(data.error_description);
} else {
errorCallback('Unable to contact server; please, try again later.');
}
}
});
};
}]);
这是控制器代码:
MyApp.controller('mainCtrl', function ($scope, LoginSrv)
{
$scope.loginUsername = 'Jan';
$scope.loginPassword = 'Maria';
$scope.userLogin = new LoginSrv();
$scope.loginError = false;
function onSuccesfulLogin () {};
function onFailedLogin(error) {};
$scope.login = function () {
userLogin.authenticate($scope.loginUsername, $scope.loginPassword, onSuccesfulLogin, onFailedLogin);
};
});
答案 0 :(得分:1)
Services are singleton so you need not give a "new",
我做了一个简短的例子,说明了你需要的相同流程并且运作良好,我希望能提供帮助:
服务
angular.module("yourapp").factory('LoginSrv', function User($http) {
var _authenticate = function(username, password) {
console.log('logged')
};
return {
authenticate: _authenticate
};
});
控制器
angular.module("yourapp").controller('mainCtrl', function ($scope, $http, LoginSrv)
{
$scope.loginUsername = 'Jan';
$scope.loginPassword = 'Maria';
$scope.userLogin = LoginSrv;
$scope.loginError = false;
$scope.login = function () {
userLogin.authenticate($scope.loginUsername, $scope.loginPassword);
};
});
答案 1 :(得分:1)
另一个答案很好地解释了您的LoginSrv
相关例外,并解释了如何实施服务/工厂。然而,它没有注意到的是两者之间的差异。
<强>工厂强> 注入工厂时,由于调用工厂功能,将为您提供返回值。
<强>服务强>
注入服务时,您将获得服务功能的实例。这类似于new serviceFunction();
。重要的是要注意angular会在第一次注入服务时执行此操作,所有其他时间注入它将会收到相同的实例。
因此,工厂用于创建对象(因此名称),服务意味着服务。所以共享逻辑。
所以在我看来(这就是全部)你的现有服务正试图做到这两点。您似乎拥有要创建的用户对象,但也有用于验证用户的方法。最好将该用户对象放在工厂中,该工厂返回create方法以创建新用户。然后将身份验证逻辑放入服务中。然后,您的身份验证不会直接与您的用户实现相关联。
可能的实施(伪代码)
.factory('userFactory', function () {
return {
create: function (details) {
return Object.create({}, {
username: {
value: details.username
},
password: {
value: details.password
},
isAuthenticated: {
value: false
}
});
}
}
});
.service('auth', function ($http) {
this.authenticate = function (username, password) {
//Build config
return $http();
}
});
.controller('test', function ($scope, userFactory, auth) {
var user = userFactory.create({
username: 'hiya',
password: 'epic secrets'
});
auth.authenticate(user.username, user.password)
.then(function (d) {
user.isAuthenticated = d.isAuthenticated;
})
.catch(SomeGenericErrorHandler);
});
任何问题只需询问