AngularJs定义了全局变量,服务'内容为null

时间:2015-06-08 08:07:29

标签: angularjs

我正在编写我的第一个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的所有控制器中。但这也不起作用 - 用户对象为null。我的第三次尝试是使用工厂:

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在另一个控制器访问该值后运行。那么如何确定/等待回应?

1 个答案:

答案 0 :(得分:0)

在aSync上下文中(比如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 已解决(以及承诺)后才会调用此方法。 因此,重要的是要了解如果您在此“解析”之前尝试访问 currentUserInTheController ,则它将未定义

要确保 currentUserInTheController 不是未定义,您需要在.then()的callBack函数中对其执行每个操作(请参阅注释中的代码)

承诺机制的科学对于在javascript中理解至关重要;)

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