为什么AngularJS与UI的路由器保持烧制$ stateChangeStart事件? [英] Why does AngularJS with ui-router keep firing the $stateChangeStart event?

查看:166
本文介绍了为什么AngularJS与UI的路由器保持烧制$ stateChangeStart事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图阻止所有的UI路由器的状态变化,直到我已经认证的用户:

I'm trying to block all ui-router state changes until I've authenticated the user:

$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)
  }
})

我拒绝所有的状态变化,直到用户已通过验证,但如果我去一个无效的URL中使用否则()的配置,我得到一个无限循环使用消息:

I reject all state changes until the user has been authenticated, but if I go to an invalid URL that uses the otherwise() configuration, I get an infinite loop with a message:

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 。与蟒蛇-m SimpleHTTPServer 7070 即成起来并转到本地主机:7070 / test.html的#/条看它爆炸在你的脸上。而直接导航到唯一有效angularjs位置不炸掉本地主机:7070 / test.html的#/富

Below is my SSCCE. Serve it up with python -m SimpleHTTPServer 7070 and go to localhost:7070/test.html#/bar to see it explode in your face. Whereas directly navigating to the only valid angularjs location does not blow up 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>

有没有我应该用它来完成这一认证阻断一种替代方法?我不知道这验证阻塞只是客户端。我没有示出在本实施例的事物的服务器侧

Is there an alternative method I should use to accomplish this authentication blocking? I do realize this authentication blocking is client side only. I'm not showing the server side of things in this example.

推荐答案

Fakeout。这是 $ urlRouterProvider $ stateProvider 之间的交互问题。我不应该使用 $ urlRouterProvider 我的,否则。我应该使用类似:

Fakeout. This is an interaction issue between $urlRouterProvider and $stateProvider. I shouldn't be using $urlRouterProvider for my otherwise. I should be using something like:

$stateProvider.state("otherwise", {
    url: "*path",
    template: "Invalid Location",
    controller: [
              '$timeout','$state',
      function($timeout,  $state ) {
        $timeout(function() {
          $state.go('/foo')
        },2000)
      }]
});

甚至transparent'ish重定向:

Or even a transparent'ish redirect:

$stateProvider.state("otherwise", {
    url: "*path",
    template: "",
    controller: [
              '$state',
      function($state) {
        $state.go('/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',
        function($stateProvider) { 

          $stateProvider.state('/foo', {
            url: '/foo',
            template: '<div>In Foo now</div>',
            reloadOnSearch: false
          })

          $stateProvider.state("otherwise", {
              url: "*path",
              template: "",
              controller: [
                        '$state',
                function($state) {
                  $state.go('/foo')
                }]
          });
        }]
      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>

这篇关于为什么AngularJS与UI的路由器保持烧制$ stateChangeStart事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆