$ rootScope在控制器中未定义

时间:2015-12-01 05:08:02

标签: angularjs ruby-on-rails-4 angularjs-rootscope

我在角度上遇到了非常奇怪的问题。我在run方法中定义了$ rootScope.user_info。但是当我在控制器中获取根作用域时,有时我在控制器中得到未定义的方法$ rootScope.user_info。知道为什么有时候我刷新页面会发生这种情况吗?

以下是代码段,

myApp.run(['$http', '$rootScope','$location','localStorageService','$window','$translate','$timeout', function($http, $rootScope,$location,localStorageService,$window,$translate,$timeout) {
    $rootScope.current_user_id = localStorageService.get("CurrentUserId");
    $rootScope.get_user_profile = function() {
        $http.get('/api/v1/employees/'+$rootScope.current_user_id).success(function(response) {
            $rootScope.user_info = response["data"]["user_info"];
        });
    };

    if ($rootScope.current_user_id) {
        $rootScope.get_user_profile();
    }
}]);

myApp.controller('ProfileCtr', ['$rootScope','$scope','Employee','fileReader','$translate','$filter','checkResponse','toaster', function($rootScope,$scope, Employee,fileReader,$translate,$filter,checkResponse,toaster){
    $scope.langs = [ { name: "en",value: "English"}, { name: "de_DE", value: "German"}, { name: "fr_FR", value: "French"} ];
    $scope.set_language = function() {
        $scope.selectLang = $filter('filter')($scope.langs, { name: $rootScope.user_info.eselected_language})[0];
    }
    $scope.set_language();
});

2 个答案:

答案 0 :(得分:0)

您的$rootScope.user_info$http.get回调中定义,这是异步方法。当您输入或刷新页面时,它当然比您尝试访问$rootScope.user_info对象的时间晚。因此,编写这样的代码是不好的做法。使用异步函数时,必须使用callbackspromises

答案 1 :(得分:0)

想象一下:

  1. $rootScope.get_user_profile发出的HTTP请求最终需要十分钟。
  2. 调用
  3. $scope.set_language,尝试访问$rootScope.user_info.eselected_language,然后失败。
  4. 十分钟后,回复终于回来并设置$rootScope.user_info
  5. 您的代码存在问题,3可能会发生2;它完全取决于HTTP请求。这就是为什么你有时而不是一直有问题的原因(因为HTTP采取的时间是可变的)。您不希望它依赖于任何内容,您希望保证 <{em> 23发生

    您可以在控制器中执行HTTP请求并将其链接起来(注意:.successdeprecated):

    $http
      .get('/api/v1/employees/'+$rootScope.current_user_id)
      .then(function(response) {
        $rootScope.user_info = response["data"]["user_info"];
      })
      .then(function() {
         // $rootScope.user_info has been set
         // your code here
      })
    ;
    

    但这不是一个好方法。您可能也希望在其他地方访问您的用户,并且在任何地方重复此结构都不会非常干。

    所以你可以做的是你可以使用UI路由器的resolve功能。它基本上说,&#34;不要实例化控制器,直到这些承诺解决了#34;。因此,您希望说,&#34;不要实例化控制器,直到获取我的用户数据的HTTP请求结算为止。

    您的代码看起来像这样:

    $stateProvider
      .state('yourStateHere', {
        url: '/yourUrlHere',
        resolve: {
          getUser: function($http, $rootScope) {
            $http
              .get('/api/v1/employees/' + $rootScope.current_user_id)
              .then(function(response) {
                $rootScope.user_info = response["data"]["user_info"];
              })
            ;
          }
        },
        controller: 'ControllerName'
      })
    ;