2015-12-01 3 views
0

Я получаю очень странную проблему в угловом. Я определил $ 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(); 
}); 
+0

чек $ значение rootScope.user_info в консоли внутри метода выполнения. см., есть ли это или нет. – Ved

+0

@Ved, если я ставлю console.log внутри обратного вызова $ http, чем он печатает объект, но если я поставлю console.log за пределами обратного вызова get_user_profile, то он будет печатать неопределенный – user9392255

+0

. Я работаю над этим. – Ved

ответ

0

Ваш $rootScope.user_info определяется в $http.get обратного вызова, который является метод асинхронной. И когда вы вводите или обновляете свою страницу, конечно, она запускается позже, чем вы пытаетесь получить доступ к объекту $rootScope.user_info. Таким образом, это плохая практика, чтобы написать такой код. При использовании асинхронных функций вы должны использовать callbacks или promises.

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 является deprecated):

$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. В основном он говорит: «Не создавайте экземпляр контроллера до тех пор, пока эти обещания не будут решены». Поэтому вы хотите сказать: «Не создавайте экземпляр контроллера до тех пор, пока 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' 
    }) 
; 
+0

Я использую $ rootScope.user_info во многих местах других контроллеров. Таким образом, можно использовать user_info, если я решительно перехожу к моему обратному адресу http? – user9392255

+0

Что делает 'resolve', это просто задерживает создание экземпляра контроллера, поэтому вы по-прежнему сможете использовать' $ rootScope.user_info' в этих контроллерах. –

Смежные вопросы