【问题标题】:AngularJS: Access connected user info from controllerAngularJS:从控制器访问连接的用户信息
【发布时间】:2016-08-25 17:58:53
【问题描述】:

我正在努力使用 AngularJS 并在此处访问连接的用户信息。我的目标是将连接用户的信息保存在服务中,以便在整个应用程序中都可用。所以我就是这样做的:

登录功能是通过一个Login服务暴露出来的,其代码如下:

(function(){
var $loginService = angular.module("RockMyTask.LoginService", [
    "satellizer",
    "RockMyTask.ApiService"
]);

/**
 * Login service
 *
 * function login(identifier, password, after)
 *  Logs the given user. Global data about the user are registered in the root scope.
 *  @param identifier The user's identifier (either email or password)
 *  @param password The user's password
 *  @param success (optional) A callback to execute when the user is successfully logged in. This callback is passed
 *  the response object.
 *  @param failure (optional) A callback to execute when the log in fails. This callback is passed the response
 *  object.
 *
 * function restore()
 *  If the user was already logged in, restore the user data in the rootScope.
 *
 * function connectedUser()
 *  Return the data of the currently connected user. If the user is not connected an empty object is returned.
 *  If the user data hasn't be fetched yet, then an empty object is returned and this object will be filled with
 *  the user data as soon as it is received.
 */
$loginService.factory("Login", ["$auth", "$rootScope", "User",
    function($auth, $rootScope, User) {
    var obj = {};
    var connectedUser = {};

    obj.logout = function() {
        $auth.logout();
        //Authorization.clear();
        connectedUser = null;
    };

    obj.login = function(identifier, password, success, failure) {
        var credentials = {
            user_identifier: identifier,
            password: password
        };

        $auth.login(credentials).then(function(auth_response) {
            // fetch user data (with both spectator and rockstar flags set to true)
            User.me(true, true).then(function(response) {
                connectedUser = response.data;
                //TODO add check for DEBUG_MODE
                console.log("Received connected user data and stored it in connectedUser var");
            }, function() {
                connectedUser = {};
            });

            // execute provided success callback
            if (_.isFunction(success)) {
                success(auth_response);
            }
        }, function(response) {
            connectedUser = null;

            // execute provided failure callback
            if (_.isFunction(failure)) {
                failure(response);
            }
        });
    };

    obj.restore = function() {
        if ($auth.isAuthenticated()) {
            User.me(true, true).then(function(response) {
                connectedUser = response.data;
            }, function() {
                connectedUser = null;
            });
        } else {
            connectedUser = null;
        }
    };

    obj.getConnectedUser = function(){
        if($auth.isAuthenticated && !connectedUser){
            User.me(true, true).then(function(response) {
                connectedUser = response.data;
            }, function() {
                connectedUser = null;
            });
        }
        return connectedUser;
    };

    obj.updateUserInfo = function(user){
        connectedUser = user;
    };

    obj.isConnectedUserRockstar = function(){
        return connectedUser.rocker != null;
    };
    obj.isConnectedUserSpectator = function(){
        return connectedUser.spectator != null;
    };

    return obj;
}]);
})();

正如您在代码中所观察到的,在成功登录后,我会启动一个 HTTP 请求 (User.me(true, ture)),然后将返回的数据(表示有关已连接用户的信息)存储在服务的一个临时变量 connectedUser 中.

为了从应用程序的任何点访问连接的用户信息,我在登录服务中实现了一个名为getConnectedUser 的函数,其代码报告如下:

obj.getConnectedUser = function(){
        if($auth.isAuthenticated && !connectedUser){
            User.me(true, true).then(function(response) {
                connectedUser = response.data;
            }, function() {
                connectedUser = null;
            });
        }
        return connectedUser;
    };

此函数检查用户是否确实通过了身份验证,以及变量 connectedUser 是否已经正确填充,如果没有,它会再次触发 HTTP 函数来检索数据(否则它只会返回 connectedUser var)。

现在,我的问题如下。成功登录后,我将用户重定向到的页面使用了一个控制器,我已将登录服务传递给该控制器。控制器尝试检索连接的用户信息,但结果是空指针。我做错了什么??

控制器中的代码(以防万一即使很简单):

$scope.user = Login.getConnectedUser();

编辑 1 在浏览器中查看控制台看到HTTP请求成功,返回数据为:

{"id":3,"email":"iCartwright@hotmail.com","name":"Michele","surname":"Imperiali","locale":"it_IT","picture":"https:\/\/storage.rockmytask.it\/users\/profile_image\/3.jpeg","birthday":"1982-06-23","gender":"M","country":"IT","province":"Lombardia","city":"Milano","zip":"20100","street":"190 Grover Expressway","mobile_phone":"(437)924-8282","home_phone":"239-250-3166x783","username":"spectator","validated":true,"timezone":"Europe\/Rome","created_at":"2016-04-01T12:50:53+0000","rocker":null,"spectator":{"description":"I need help with my garden !"}}

如前所述,当我尝试访问控制器中$scope.user 的变量时,我得到一个空指针异常。

【问题讨论】:

标签: angularjs service controller


【解决方案1】:

我认为这个问题与

, function() {
            connectedUser = null;
        }

您将 connectedUser 设置为 null 是否有原因?如果原因是因为您想将其设置为 null 如果您从后端收到错误或返回错误,那么请执行以下操作:

obj.getConnectedUser = function(){
    if($auth.isAuthenticated && !connectedUser){
        User.me(true, true).then(function(response) {
            connectedUser = response.data;
        }, function(error) {
            connectedUser = null;
        });
    }
    return connectedUser;
};

如果你得到一个错误的响应,这只会将 connectUser 设置为 null,截至目前,看起来 connectedUser 总是被设置为 null 并解释你的空指针。

【讨论】:

  • 谢谢杰弗里,但我不认为你的解决方案是好的。 then 函数的符号是​​定义成功和失败的两个函数。我的函数是第二个参数,只有在 HTTP 请求失败的情况下才会触发。其实即使我评论了connectedUser = nullbody,问题还是一样的……
  • 对不起,我还没有足够的声誉发表评论。我的另一个想法是该函数实际上应该返回承诺,而不是等待函数中的承诺。所以你会让函数返回http请求。然后在控制器中是 Login.getConnectedUser().then(function(response){ $scope.user = response.data});
  • 嘿,杰弗里,是的,你是对的。我没有像你说的那样做,因为我想在服务中执行 then ,将连接的用户信息存储在那里,并使其可用于来自应用程序其他部分的后续请求。但是,您的评论为我指明了正确的方向。我将很快发布我的解决方案。干杯!
猜你喜欢
  • 2019-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-23
  • 2021-07-21
  • 1970-01-01
  • 1970-01-01
  • 2014-02-22
相关资源
最近更新 更多