我有以下服务(伪代码)
app.service('user', function($http) {
function login(email, password, callback) {
// login user
// set isLoggedIn to true
// assign the returned user object to userData
// issue callback
};
return {
isLoggedIn: false,
userData: null,
login: login
};
});
这是我的登录控制器:
app.controller('LoginController', function($scope, $http, $location, user) {
user.login($scope.email, $scope.password, function(isSuccess, data, status) {
if (isSuccess) { $scope.onSuccessfulLogin(); }
else { $scope.loginStatusMessage = data; }
});
$scope.onSuccessfulLogin = function() {
$location.path('/someOtherPage');
};
});
这是/someOtherPage
app.controller('SomeOtherPageController', function($scope, $http, $modal, user) {
// lots of stuff in here
// I put a breakpoint on the first line and user.isLoggedIn is false
// even though it was definitely set to true when the user logged in.
)};
使用user
服务登录后发出回调一次,如果登录成功,用户将被带到另一个具有不同控制器的页面,其中注入了上述user
服务。问题是如果登录成功,虽然我可以看到正确分配了isLoggedIn
和userData
变量,但在新控制器中它们分别保留false
和null
。
我错过了什么吗?每当注入user
像单身人士时,我都需要相同的值。
由于
答案 0 :(得分:4)
您需要使用服务,而不是工厂。服务返回函数的实例。这意味着一旦注入,每个人都将使用相同的实例。在你的情况下,你正在使用一个工厂(你发布我的答案后你已经更新了),每次注入它都会返回从函数返回的值。关于此问题的最佳SO帖子是AngularJS: Service vs provider vs factory
当我想把这一点推回家时,我倾向于使用服务。我希望人们知道他们是否注入了这个,每个人都将共享同一个对象。我经常将它与Cache和用户一起使用。
app.service('user', function($http) {
var that = this;
this.isLoggedIn = false;
this.login = function(email, password, callback) {
that.isLoggedIn = true;
// login user
// set isLoggedIn to true
// assign the returned user object to userData
// issue callback
};
return this;
})
答案 1 :(得分:1)
实际上,角度上的所有服务都是单身。有关详细信息,请查看此stackoverflow。 Anywho,关于你的问题,直接来自Angular docs:
Angular服务是:
Lazily实例化 - Angular仅在实例化时实例化服务 应用程序组件取决于它。
单身人士 - 依赖于服务的每个组件都会获得对单个实例的引用 由服务工厂生成。
您应该使用工厂,因为您只需要重新创建透明模块模式,Angular通过工厂实现,服务是构造函数。
除了你的服务只是为两个值返回null和false之外,这两个都是非常重要的,无论你在服务内部将它们更改为什么,值都将始终为null和false。您正在返回一个对象,因此您需要正确连接键值对。
app.factory('user', function($http) {
var service = {};
service.userData = null;
service.isLoggedIn = false;
service.login = function(email, password, callback) {
// login user
// set isLoggedIn to true
this.isLoggedIn = true;
// assign the returned user object to userData
this.userData = someValue;
// issue callback
}
return service;
});
答案 2 :(得分:1)
这里的问题是你要返回一个用null和false实例化的对象:
return {
isLoggedIn: false,
userData: null,
login: login
};
它应该返回另一个闭包变量。
return {
isLoggedIn: myIsLoggedIn,
userData: myUserData,
login: login
};
在myUserData
函数中设置myIsLoggedIn
和login
的位置。或者另一种方法是返回将这些值作为@Sten提及的方法返回的方法。
答案 3 :(得分:0)
我认为问题不在服务中,而是在控制器中:可能你有一个范围属性设置为isLoggeIn值,类似于:
$scope.isLoggedIn = user.isLoggedIn
但是,如果没有用户服务值的观察者,则您的范围属性不会更改其值。 你能发布控制器代码吗?