1

我在角度方面遇到了非常奇怪的问题。我在 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();
});
4

2 回答 2

0

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

于 2015-12-01T05:25:27.187 回答
0

想象一下:

  1. $rootScope.get_user_profile发出一个最终需要十分钟的 HTTP 请求。
  2. $scope.set_language被调用,它试图访问$rootScope.user_info.eselected_language,但失败了。
  3. 十分钟后,响应终于回来并设置$rootScope.user_info

您的代码的问题是3可能发生在2; 它完全取决于 HTTP 请求。这就是为什么有时而不是所有时间都会出现问题的原因(因为 HTTP 花费的时间是可变的)。你不希望它依赖于任何东西,保证在.2 3


您可以在控制器中执行 HTTP 请求并像这样链接它(注意:.success弃用):

$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 路由器的解析功能。它基本上说,“在这些承诺解决之前不要实例化控制器”。所以你想说,“在获取我的用户数据的 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'
  })
;
于 2015-12-01T06:29:25.943 回答