angularjs - 为什么带有 ui-router 的 AngularJS 不断触发 $stateChangeStart 事件?

标签 angularjs angular-ui-router

我正在尝试阻止所有 ui-router 状态更改,直到我对用户进行了身份验证:

$rootScope.$on('$stateChangeStart', function (event, next, toParams) {
  if (!authenticated) {
    event.preventDefault()
    //following $timeout is emulating a backend $http.get('/auth/') request
    $timeout(function() {
      authenticated = true
      $state.go(next,toParams)
    },1000)
  }
})

在用户通过身份验证之前,我拒绝所有状态更改,但是如果我转到使用 otherwise() 的无效 URL配置,我得到一个带有消息的无限循环:
Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: [["fn: $locationWatch; newVal: 7; oldVal: 6"],["fn: $locationWatch; newVal: 8; oldVal: 7"],["fn: $locationWatch; newVal: 9; oldVal: 8"],["fn: $locationWatch; newVal: 10; oldVal: 9"],["fn: $locationWatch; newVal: 11; oldVal: 10"]]

下面是我的 SSCCE .用 python -m SimpleHTTPServer 7070 服务然后转至 localhost:7070/test.html#/bar看到它在你脸上爆炸。而直接导航到唯一有效的 angularjs 位置不会失败 localhost:7070/test.html#/foo :
<!doctype html>
  <head>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.min.js"></script>
  </head>
  <body ng-app="clientApp">
    <div ui-view="" ></div>

    <script>
      var app = angular.module('clientApp', ['ui.router'])

      var myRouteProvider = [
                '$stateProvider', '$urlRouterProvider',
        function($stateProvider,   $urlRouterProvider) { 
          $urlRouterProvider.otherwise('/foo');
          $stateProvider.state('/foo', {
            url: '/foo',
            template: '<div>In Foo now</div>',
            reloadOnSearch: false
          })
        }]
      app.config(myRouteProvider)

      var authenticated = false
      app.run([
                 '$rootScope', '$log','$state','$timeout',
        function ($rootScope,   $log,  $state,  $timeout) {
          $rootScope.$on('$stateChangeStart', function (event, next, toParams) {
            if (!authenticated) {
              event.preventDefault()
              //following $timeout is emulating a backend $http.get('/auth/') request
              $timeout(function() {
                authenticated = true
                $state.go(next,toParams)
              },1000)
            }
          })
        }
      ])
    </script>
  </body>
</html>

我应该使用替代方法来完成此身份验证阻止吗?我确实意识到这种身份验证阻塞只是客户端。在这个例子中,我没有展示服务器端的东西。

最佳答案

当您使用 $urlRouterProvider.otherwise("/foo) 与 $stateChangeStart 的组合时,看起来这是 ui-router 的一个错误。

问题 - https://github.com/angular-ui/ui-router/issues/600

Frank Wallis 提供了一个很好的解决方法,使用更长形式的 else 方法,它将函数作为参数:

$urlRouterProvider.otherwise( function($injector, $location) {
            var $state = $injector.get("$state");
            $state.go("app.home");
        });

干得好,弗兰克!

关于angularjs - 为什么带有 ui-router 的 AngularJS 不断触发 $stateChangeStart 事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25065699/

相关文章:

javascript - Angular JS 中的必填字段验证

javascript - UI-router 中的 ControllerProvider 导致错误

javascript - Angular UI 路线状态未显示

angularjs - 根据当前状态向 ui-view 添加一个类

javascript - 将用于解析的函数打包为可重用模块

javascript - 使用 Node.js 在 HTML5 模式下进行 Angular 路由

javascript - 服务中返回响应

html - Angular.js 以旧方式提交表单

AngularJS ngTable 在处理大量数据时速度很慢

node.js - SailsJS 与 BreezeJS 的 SPA 后端验证