AngularJs定义全局变量,service内容为空。

4

我正在编写我的第一个AngularJS应用程序。该应用程序需要在不同的控制器中了解当前用户。当前用户是通过rest调用检索的。首先,我只是使用$scope在页面顶部添加了当前用户信息:

var currentUser = {};
app.controller('currentUserCtrl', function($scope, $http) {
    $scope.currentUser = null;
    $http.get(rootUrl + '/timetracker/user/current').success(
            function(response) {
                $scope.currentUser = response;
                currentUser = response;
            });
}

);

这个控制器本身是正常工作的,但是其他控制器无法访问“currentUser”。我第二次尝试(在阅读有关全局变量的文章之后)是使用$rootScope。所以我改变了上面的$rootScope.currentUser = response;并省略了var currentUser。我在所有控制器中都添加了$rootScope,并尝试获取currentUser.id。但是这也没有起作用 - 用户对象为空。我的第三次尝试是使用一个工厂:

app.factory('currentUser', function($http){
    var currentUser = {};
    $http.get(rootUrl + '/timetracker/user/current').success(
            function(response) {
                currentUser = response;
            });
    return currentUser;
});

我的控制器现在注入了“currentUser”,但是它也是null(我想获取的所有值都是“未定义”的)。那么如何使当前用户全局可用?

可能是在异步调用和变量写入成功之前使用了currentUser?如何确保currentUser调用已经完成?

编辑 使用currentUser的控制器:

app.controller('createBookingCtrl', function($scope, $http, $filter, currentUser) {
    //list of projects for current user (usersprojects)
    $scope.projectsList = {};
    $http.get(rootUrl + '/timetracker/usersprojects/user/' + currentUser.id).success(function(response) {
        for (var i = 0; i < response.length; ++i)
            //map users project by projects name
            $scope.projectsList[response[i].project.name] = response[i];
    });
});

currentUser.id的值未定义。

第二次编辑 我刚刚用js调试器测试了一下:在工厂函数中,currentUser = response在其他控制器访问该值之后运行。那么如何确保/等待响应呢?


你能否附上你正在使用的控制器代码来检查currentUser值(在那里你得到了未定义)? - OrenD
通过你的第三种方法,你是如何在控制器中访问工厂变量的?能否在这里发布一下? - newstackoverflowuser5555
你必须像这样访问它,因为它返回一个 Promise 数据。$scope.userId = currentUser.getUser().then(function(result) { return result.id ; }); - newstackoverflowuser5555
Hurix感谢您 - 您能否将其转化为答案 - 我会在此期间尝试... - dermoritz
1个回答

0
在异步上下文(如JavaScript)中,一切都与 promises 有关。
我猜应该将操作/提供“currentUser”的责任放在一个服务/工厂中。而你的所有控制器都将在那里请求“currentUser”。这样,你就可以确保始终获得有效版本的“currentUser”。问题在于如何知道何时准备好了这个“currentUser”对象,这就是为什么你需要使用会告诉你何时采取行动的promise object
假设你有一个名为“CurrentUserService”的服务,其中包含一个“getCurrentUser”方法,该方法将返回一个promise对象:
app.service('CurrentUserService', function($http) {
  var currentUser,
      urlToCurrentUser = 'http://example.com/currentUserAPI';

  function getCurrentUser() {
    return $http.get(urlToCurrentUser).success(
      function(response) {

        currentUser = response;

        return currentUser;
      });
  }

  return {
    getCurrentUser: getCurrentUser
  };
});

现在,让我们看看需要这个currentUser的控制器将如何表现。

首先,控制器需要访问我们的CurrentUserService。然后,它只需调用服务上的getCurrentUser

app.controller('SomeControllerController', function(CurrentUserService) {
  var currentUserInTheController;

  ...
  CurrentUserService.getCurrentUser().then(function(currentUser){
       currentUserInTheController = currentUser;
       // from here and only in the current function, currentUserInTheController is defined for sure !
  });
  ...
});

关键在于.then()方法。 这个方法只会在$http解析(以及promise)后调用一次。 所以重要的是要明白,在这个“解析”之前,如果你尝试访问currentUserInTheController,它将是undefined

为了确保currentUserInTheController不是undefined,你需要在.then()的回调函数中执行每个操作(参见代码中的注释)

理解javascript中的promise机制是至关重要的;)

阅读更多: http://andyshora.com/promises-angularjs-explained-as-cartoon.htmlAngularJS:何时使用promises?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接