javascript - 用户界面路由器 : How should you prevent toState from showing while you're checking authorization?

标签 javascript angularjs angular-ui-router

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

我正在使用 $on($stateChangeStart) 对路由进行身份验证。我这样做的方式存在一个问题:如果用户试图访问他无权查看的状态,该状态将在我的代码重定向他之前短暂显示。

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

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

  1. body 上的“闪烁”display: none -> display: block
  2. 隐藏和重新显示这么大一部分 DOM 的成本很高(或者是吗?)。

应该如何处理这种情况?

Plunker

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; 
}
<!DOCTYPE html>
<html ng-app='app'>

  <head>
    <script data-require="angular.js@1.4.6" data-semver="1.4.6" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.min.js"></script>
    <script data-require="ui-router@0.2.11" data-semver="0.2.11" src="https://rawgit.com/angular-ui/ui-router/0.2.11/release/angular-ui-router.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
    <base href='/'>
  </head>

  <body>
    <ul>
      <li><a ui-sref='home'>home</a></li>
      <li><a ui-sref='one'>state one</a></li>
      <li><a ui-sref='two'>state two</a></li>
    </ul>
    
    <div ui-view></div>
  </body>

</html>

最佳答案

您的 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

关于javascript - 用户界面路由器 : How should you prevent toState from showing while you're checking authorization?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33059308/

相关文章:

angularjs - 为什么angularjs会两次调用 `name()`函数?

AngularJS - Angular UI-Router 仅重新加载嵌套 View ,而不是父 View

javascript - 类型错误 : Cannot read property 'go' of undefined

javascript - Java Jsoup : Extract all the text

javascript - jQuery UI DatePicker 主题

javascript - NodeJs forEach 请求 promise 在返回之前等待所有 promise

JavaScript/HTML : How to position object to right of page?

angularjs - 如何使用 jasmine 测试 window.location.href

angularjs - Angular -> Web API 2 : "No ' Access-Control-Allow-Origin' header"

angularjs - 两条动态子路由 - ui-router