Отменить маршрут и перенаправить на другой маршрут без отображения исходного содержимого в AngularJS

Я хочу проверить службы http, чтобы узнать, проверен ли пользователь и имеет ли он разрешение на просмотр определенной страницы (контроллера) в AngularJS 1.2.0rc1.

У меня такой сценарий: Пользователь A хочет посетить http://www.example.com/content. Теперь этот контент не должен быть доступен, если он или она не аутентифицированы. Если пользователь не аутентифицирован, он должен быть перенаправлен на http://www.example.com/login.

Теперь мне это удалось, но я кратко просмотрел отображаемый html страницы контента. Я не хочу этого. Как переадресовать на страницу входа, не отображая страницу содержимого?

Я регистрирую маршруты как таковые:

$routeProvider.when('/login', route.resolve('Login', false))
$routeProvider.when('/content', route.resolve('Content', true))

Теперь я пробовал это:

$rootScope.$on('$routeChangeStart', function (event, route) {
    if (route.requiresLogin) {
        $http.get('/api/user/loggedin/').then(function (response) {
            if (response !== 'true') {
                $location.path('/login');
            }
        });
    }
});

Что работает, но я все еще вижу, что содержимое html другой страницы (содержимого) мигает.

Я читал, что здесь, что вы также можете попытаться изменить функции разрешения при разрешении маршрута:

    var resolve = function (baseName, requiresLogin) {
    var routeDef = {};
    var dependencies = [routeConfig.getControllersDirectory() + baseName + 'Controller.js'];

    routeDef.templateUrl = routeConfig.getViewsDirectory() + baseName.toLowerCase() + '.html';
    routeDef.controller = baseName + 'Controller';
    routeDef.requiresLogin = requiresLogin;
    routeDef.resolve = {
        load: ['$q', '$rootScope', '$http', '$location', function ($q, $rootScope, $http, $location) {
            console.log(requiresLogin);
            if (requiresLogin) {
                return checkLoggedIn($q, $rootScope, $http, $location);
            } else {
                return resolveDependencies($q, $rootScope, dependencies);
            }
        }]
    };

    return routeDef;
}

Но здесь также отображается короткая страница.

Надеюсь, что вы можете мне помочь.

Ответ 1

Первый ответ должен работать, но для этого используйте $q. Я бы использовал defer.resolve() или defer.reject("rejection_reason"), тогда я бы прослушал $routeChangeError в контроллер верхнего уровня, связанный с элементом за пределами ng-представления, которым управляет routeProvider.

Итак, в вашем HTML, что-то вроде:

<body ng-app="app" ng-controller="DocumentCtrl">
  <div ng-view>
  </div>
</body>

Тогда для вашего маршрута будет определено что-то вроде:

when('/home', {
  templateUrl: templateUrl blah,
  controller: baseName + 'Controller',
  resolve: {
    load: function($q, MY_USER_SERVICE){
      var defer = $q.defer();
      if(~MY USER LOGGED_IN LOGIC RETURNS TRUE~){
        defer.resolve();
      } else {
        defer.reject("not_logged_in");
      }
      return defer.promise;

    }
  }
}).

Затем мой контроллер DocumentCtrl будет содержать:

$scope.$on("$routeChangeError", function(evt,current,previous,rejection){
  if(rejection == "not_logged_in"){
    //DO SOMETHING
  } else {
    //OR DO SOMETHING ELSE
  }
});

Я запускаю приведенное выше, и нет флеш-просмотра каких-либо представлений, которые нельзя загружать.