角度服务变量不更新

时间:2014-04-13 20:14:30

标签: javascript angularjs

我有以下服务(伪代码)

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服务。问题是如果登录成功,虽然我可以看到正确分配了isLoggedInuserData变量,但在新控制器中它们分别保留falsenull

我错过了什么吗?每当注入user像单身人士时,我都需要相同的值。

由于

4 个答案:

答案 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函数中设置myIsLoggedInlogin的位置。或者另一种方法是返回将这些值作为@Sten提及的方法返回的方法。

答案 3 :(得分:0)

我认为问题不在服务中,而是在控制器中:可能你有一个范围属性设置为isLoggeIn值,类似于:

$scope.isLoggedIn = user.isLoggedIn

但是,如果没有用户服务值的观察者,则您的范围属性不会更改其值。 你能发布控制器代码吗?