【问题标题】:AngularJs defined global variable, service' content is nullAngularJs 定义全局变量,服务内容为空
【发布时间】:2015-08-22 14:49:51
【问题描述】:

我正在编写我的第一个 AngularJs 应用程序。应用需要知道不同控制器中的当前用户。当前用户通过休息调用检索。首先,我只是使用 $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”,但这也是空值(我想要获取的所有值都是“未定义”)。那么如何让当前用户全局可用呢?

难道是在异步调用和写入变量成功之前使用了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 值(未定义的位置)的控制器代码?
  • 通过您的第三种方法,您如何访问控制器中的工厂变量。可以发在这里吗
  • 你必须像这样访问它,因为它返回一个承诺数据。 $scope.userId = currentUser.getUser().then(function(result) { return result.id ; });
  • 好力谢谢 - 你能回答一下吗 - 我会在此期间尝试......

标签: angularjs


【解决方案1】:

在 aSync 上下文中(如 javascript),一切都与承诺有关。

我的猜测是将操作/提供 currentUser 的责任放在服务/工厂中。你所有的控制器都会在那里询问 currentUser。这样您就可以确保始终获得您的 currentUser 的有效版本。问题是要知道这个 currentUser 对象何时准备就绪,这就是为什么您需要使用promise object 来告诉您何时采取行动。

假设你有一个带有 getCurrentUser 方法的 CurrentUserService,这个方法将返回一个 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() 方法。 这个方法只会在 $httpresolved (以及promise)时被调用。 因此,重要的是要了解,如果您在此“解决”之前尝试访问 currentUserInTheController,它将是 undefined

要确定有一个 currentUserInTheController 而不是 undefined,您需要在 .then() 的回调函数中对其执行所有操作(请参阅中的注释代码)

promise 机制的科学对于理解 javascript 至关重要;)

阅读更多: http://andyshora.com/promises-angularjs-explained-as-cartoon.htmlAngularJS : Where to use promises?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-15
    • 2020-02-23
    • 2014-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多