UI路由器:在检查授权时,如何防止显示toState?

时间:2015-10-10 21:49:14

标签: javascript angularjs angular-ui-router

编辑:使用resolve的建议方法对我不起作用。 $stateChangeStart事件似乎在解决问题之前发生。 Plunker

我正在使用$on($stateChangeStart)对路由进行身份验证。我这样做的方式存在一个问题:如果用户试图访问他未经授权可以看到的状态,则在我的代码重定向之前会暂时显示状态。

要解决此问题,最好的方法似乎是使用event.preventDefault() + $state.go(toState.name, {}, { notify: false }),但{ notify: false }known bug

我不确定处理这种情况的好方法是什么。我唯一的想法是切换display的{​​{1}}属性,但我不喜欢这个解决方案。

  1. “闪烁”body - > display: none上的display: block
  2. 隐藏和重新显示如此大部分的DOM(或者是它?)是很昂贵的。
  3. 如何处理这种情况?

    Plunker

    body
    angular
      .module('app', ['ui.router'])
      .config(config)
      .run(run)
    ;
    
    function config($locationProvider, $urlRouterProvider, $stateProvider) {
      $locationProvider.html5Mode(true);
      $urlRouterProvider.otherwise('/');
      
      $stateProvider
        .state('home', {
          url: '/',
          template: '<p>home</p>'
        })
        .state('one', {
          url: '/one',
          template: '<p>one</p>',
          authenticate: true
        })
        .state('two', {
          url: '/two',
          template: '<p>two</p>'
        })
      ;
    }
    
    function run($rootScope, $state, $timeout) {
      $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState) {
        if (toState.authenticate) {
          // event.preventDefault();
          angular.element(document.body).css('display', 'none');
          if (isAuthenticated(false)) {
            // $state.go(toState.name, {}, { notify: false });
            angular.element(document.body).css('display', 'block');
          }
          else {
            $timeout(function() {
              $state.go('two');
              angular.element(document.body).css('display', 'block');
            }, 2000);
          }
        }
      });
    }
    
    function isAuthenticated(hardcode) {
      return hardcode; 
    }

1 个答案:

答案 0 :(得分:2)

您的if遗失!

防止事件处理问题并且不允许路由加载

function run($rootScope, $state, $timeout) {
  $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState) {
    if (toState.authenticate) {
      if (!isAuthenticated()) {
        event.preventDefault();
        // can redirect if needed here
      }
    }
  });
}

function isAuthenticated() {
  return false; 
}

DEMO