1

каждый раз, когда изменяется маршрут, я проверяю, установлена ​​ли переменная с текущими зарегистрированными данными пользователя, если эта переменная не установлена, я просто перенаправляюсь на страницу входа.Отложить создание контроллеров/служб при запуске приложения angularjs

Теперь я пытаюсь достичь какой-то функциональности «помнить меня», поэтому каждый раз, когда маршрут изменяется, если пользователь переменной не существует, а не перенаправляется на страницу входа в систему, я проверяю локальное хранилище на «authtoken», если установлено, я вызываю функцию проверки, передающую authtoken на сервер, которая возвращает пользователя, и приложение будет работать так же, как после входа в систему (который возвращает того же пользователя, что и функция проверки).

Я уверен, что это не лучший способ сделать это.

Если я перезагружаю страницу, первое, что я запускаю функцию проверки, которая отправляет authtoken на сервер и ждет ответа, если пользователь существует, это значение присваивается переменной в корневом каталоге.

У меня есть различные услуги, которые используют переменную в rootscope, например

angular.module('myApp') 
    .service('AdminService', function AdminService($rootScope, $http, StorageService) { 
    var authtoken = StorageService.get('authtoken'); 
    var clientId = $rootScope.loggedUser.id; 

и, конечно же, когда функция проверки работает он ожидает ответа, но служба в настоящее время экземпляр и $ rootScope.loggedUser .id не существует.

Как я могу сказать приложению подождать, пока функция проверки получит ответ?

Это мой код

.... 
}).run(function($rootScope, $location, AuthService, StorageService) { 

var intended = $location.path(); 

AuthService.check().success(function(data) { 
    if(data.user) { 
     $rootScope.loggedUser = data.user; 
     $location.path(intended); 
    } else $location.path('login'); 
}); 
$rootScope.$on('$routeChangeStart', function() { 

    if($rootScope.loggedUser) { 
    .... 

Например, если пользователь закладка страницы «myapp.com/#/admin/users», я не хочу, чтобы перенаправить на вход в систему, если у меня есть в локальное хранилище authtoken, но это приводит к созданию экземпляра контроллера, который использует службу, которая нуждается в $ rootScope.loggedUser.id, который еще не заселен.

И я хочу запустить проверку функции только при загрузке страницы (не каждый раз, когда пользователь меняет маршрут).

+0

Посмотрите на '$ routeProvider 'и свойство' resolve' маршрута. –

+0

В этом случае он должен разрешать каждый раз, когда пользователь посещает этот маршрут? Поскольку я хочу одноразовую проверку, когда пользователь загружает приложение, мне не нужно проверять каждый раз, когда пользователь посещает маршрут. – peppeocchi

+0

Тогда вы могли бы использовать метод '.run', но с проверкой подлинности я предлагаю использовать решение, потому что аутентификация может истечь и т. д. Вам не нужно каждый раз вызывать вызов сервера, просто изучите токен аутентификации для истечения срока действия –

ответ

1

Я бы посоветовал пересмотреть ваш дизайн, если вам нужен служебный звонок для проверки вашего токена аутентификации. У токенов Auth обычно есть время истечения, хранящееся в них, поэтому вы можете просто проверить, находитесь ли вы в течение срока действия без вызова сервера. Вы не ставите под угрозу безопасность, так как токены аутентификации подписываются сервером и проверяются при выполнении вызовов сервера, чтобы сделать что-нибудь полезное. Таким образом, при нормальных обстоятельствах никакого отдельного вызова check не требуется.

Но, если вы настаиваете, этот прецедент лучше всего обрабатывать с помощью свойства resolve маршрута. Это означает, однако, что каждый маршрут, который заботится о состоянии входа пользователя, должен иметь определенное свойство разрешения. Это не означает, что вам нужно вызвать службу при каждом изменении маршрута.

Вместо того, чтобы использовать $rootScope.loggedUser для сохранения пользователя, его следует кэшировать AuthService и вводить через параметр resolve.

Таким образом, вы можете сделать следующее:

$routeProvider 
    .when("some/secure/route", { 
      controller: "SecureCtrl", 
      resolve: { 
      user: AuthService.checkUser 
      } 
     }); 

И в вашем AuthService:

... 
checkUser: function(){ 
    var deferred = $q.defer(); 

    if (cachedUser){ 
    deferred.resolve(cachedUser); 
    } else { 

    AuthService.check().success(
     function(data){ 
      // cachedUseris defined at AuthService's scope 
      cachedUser = data.user; 
      deferred.resolve(data.user); 
     }); 
    } 

    return deferred.promise; 
} 

Затем в контроллерах:

.controller("SecureCtrl", function(user){ 
    $scope.userId = user.id; 
} 
+0

Мне очень нравится этот подход, спасибо, но я не следую логике. Никогда не использовал провайдера .... Мне нужно ввести поставщика в .config ( , поэтому я создал AuthServiceProvider, который возвращает функцию проверки, которая использует $ http и StorageService, но я в цикле, также AuthServiceProvider требует, чтобы $ httpProvider и StorageServiceProvider ... похоже, что я что-то делаю неправильно – peppeocchi

+0

Возможно, мне что-то не хватает ... зачем вам нужно создать AuthServiceProvider? –

+0

Я сказал, что делаю что-то неправильно .... I был инъекцией AuthService в неправильном месте, теперь он отлично работает, спасибо! Приложение является административной панелью, поэтому каждый маршрут защищен, теперь мне нужно задать решение по каждому маршруту, было бы здорово, если бы я мог сделать это в одном месте, за каждый маршрут. Еще раз спасибо! – peppeocchi