2015-03-30 2 views
0

У меня есть веб-приложение и переменная app с модулем myApp.
У меня есть 3 страницы: /login, /registration и /. Мои $routeChangeStart определяется вести себя следующим образом:

  1. Проверить, если глобальная переменная user определена, если да, то перейти к шагу 4
  2. Проверьте, где пользователь хочет идти: если он не хочет идти в /login или /registration выполните event.preventDefault() и проверьте, есть ли действующий сеанс (через файл cookie) и попробуйте разрешить пользователю. Если пользователь авторизован, установите глобальную переменную user и перенаправьте его на нужную страницу, иначе отправьте его на страницу /login.
  3. Если он хочет перейти на /login или /registration ничего не делать (мы в этом случае нет пользовательской переменной, и я хочу войти или зарегистрироваться).
  4. Проверьте, где пользователь хочет идти: если он хочет пойти в /login или /registration сделать event.preventDefault() и перенаправить его на главную страницу / (пользователь имеет действительный сеанс, не нужно войти еще раз).

Логика работает хорошо, пока мы не попали F5 (я знаю, что вытирает $rootScope, но за счет дополнительного вызова AJAX мы должны быть хорошо с ним), а в / страницы с действительными куками сессии. Приложение просто не перенаправляет на правильный шаблон, страница остается пустой. Если мы вместо этого вставляем URL-адрес около / (например, /blah), все работает нормально.

Вот мой app.js:

(function() { 
    angular.module("myApp", ["controllers", "services", "directives", "ngRoute"]) 
     .config(["$httpProvider", "$routeProvider", function ($httpProvider, $routeProvider) { 
      $httpProvider.defaults.withCredentials = true; 
      $httpProvider.defaults.headers.post['Content-Type'] = 'application/json; charset=utf-8'; 

      $routeProvider 
       .when("/login", { 
        controller: "LoginController", 
        templateUrl: "app/partials/login.html" 
       }) 
       .when("/registration", { 
        controller: "RegistrationController", 
        templateUrl: "app/partials/registration.html" 
       }) 
       .when("/", { 
        controller: "MainController", 
        templateUrl: "app/partials/home.html" 
       }) 
       .otherwise("/"); 

     }]) 
     .run(function ($rootScope, $location, $http) { 
      $rootScope.$on('$routeChangeStart', function (event, next, current) { 

       if (!$rootScope.user) { 

        if (next && next.$$route && (next.$$route.originalPath !== "/login" && next.$$route.originalPath !== "/registration")) { 
         event.preventDefault(); 

         $http.get("http://localhost:8080/myapp/api/user?self=true") 
          .success(function (data) { 
           $rootScope.user = data; 
           $location.path(next.$$route.originalPath); 
          }) 
          .error(function() { 
           $location.path("/login"); 
          }); 
        } 
       }else{ 
        if (next && next.$$route && (next.$$route.originalPath === "/login" || next.$$route.originalPath === "/registration")){ 
         event.preventDefault(); 
         $location.path("/"); 
        } 
       } 
      }); 
     }); 

    angular.module("controllers", []); 
    angular.module("services", []); 
    angular.module("directives", []) 
})(); 

Почему не $location.path(next.$$route.originalPath); в AJAX работы вызова .success()? Обратите внимание, что если я его заменим, например, $location.path("/blah"); перенаправляется правильно (но все еще не работает с $location.path("/");).

ответ

3

Я думаю, когда вы звоните event.preventDefault() угловатые пытается Откат в текущем пути. Однако, если вы входите в первый раз, текущий путь не определен и поэтому угловой помещает корневой путь («/») в качестве текущего пути. Таким образом, $ location.path пытается пойти в том же месте, где вас угловало, закончив тем, что ничего не делал.

Итак, вы должны сделать $ route.reload(), а не $ location.path().

$http.get("http://localhost:8080/myapp/api/user?self=true") 
         .success(function (data) { 
          $rootScope.user = data; 
          if ($location.path() === next.$$route.originalPath) { 
           $route.reload(); 
          } else { 
           $location.path(next.$$route.originalPath); 
          } 
         }) 
         .error(function() { 
          $location.path("/login"); 
         }); 
+0

Спасибо @Sandro, ваше решение работает! – Narmer

0

$rootScope.$evalAsync(function() { $location.path('/c'); });

Это должно работать нормально. Примечание: event.preventDefault(); будет функционировать только в угловых 1.3+, но вы не можете изменить $ местоположение непосредственно, нуждается в $ evalAsync

+0

Уже пробовал, поведение в точности то же самое ... Я запускаю «угловой 1.3.15' битва (и ту же версию« углового маршрута », конечно). Но возникает вопрос: имеет ли 'c' в'/c' некоторый смысл или его случайный? Потому что с '/ c' работает, но это просто обходной путь, как'/blah', который я пробовал. Мне нужно отправить пользователя в 'next. $$ route.originalPath' location ... – Narmer

+0

Вы выводили' '' next. $$ route.originalPath'''? Вы попробовали с помощью $ apply? –

+0

Да, правильное расположение ('/', отладка с хром) и да без результата (фактически с исключением, потому что мы уже находимся внутри цикла дайджеста) – Narmer

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