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

次のことを想像してください。

  1. $rootScope.get_user_profile最終的に 10 分かかる HTTP 要求を作成します。
  2. $scope.set_languageが呼び出され、 にアクセスしようとして$rootScope.user_info.eselected_language失敗します。
  3. 10分後、ようやく応答が戻ってきて$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
  })
;

しかし、それは本当に良い方法ではありません。おそらく、他の場所でもユーザーにアクセスしたいと思うでしょう。この構造をどこでも繰り返すことは、あまり DRY ではありません。

そこでできることは、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 に答える