当前位置: 首页 > 面试题库 >

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

巴学潞
2023-03-14
问题内容

我试图阻止所有ui路由器状态更改,直到我对用户进行身份验证为止:

$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 7070localhost: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
和之间的交互问题$stateProvider。我不应该用$urlRouterProvider我的otherwise。我应该使用类似的东西:

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

甚至是透明的重定向:

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


 类似资料:
  • 在JavaScript中,我按住两个键,并且被完美触发。当我释放其中一个键时,被触发。到目前为止一切都很好。但是我仍然按住一个键,那么为什么没有被触发呢?我需要在我的游戏中发生这种情况。我做错了什么吗?这是预期的反应吗?有什么解决办法吗?

  • 问题内容: 我正在尝试在应用程序中使用AngularJS,并在某种程度上取得了成功。 我能够获取数据并将其显示给用户。我有一个按钮,我想通过该按钮发布DELETE请求。下面是我的代码。 这是获取信息并将其显示给用户的功能。 数据已获取并正确显示。 但是,单击删除按钮后,不会触发其中的代码。在GoogleChrome浏览器的开发人员工具中,我可以看到为代码生成了有效值,但未触发代码。从我尝试去掉花括

  • 我需要测试一个服务类,但是当我试图模拟dao类时,它没有被触发,因此不能使用ThenReturn()。 我认为问题是因为我在服务类(Spring MVC 3.1)中为我的Dao和@Autowired使用了一个接口: 接口: 执行情况: 成功了!

  • 问题内容: 我的代码中有一个。我已添加。但是它还是没有被触发。我已经尝试了很多时间,但是没有找到解决方案。 但是控制台中没有任何内容。请建议我我在做什么错。 问题答案: FocusListener不是JComboBox的适当监听器,另外一个监听器可以创建无限循环(尤其是可编辑的JComboBox), 的FocusListener是异步的,有时是太难捕捉事件是正确的订单特别是在案件JComponen

  • 我在使用Discord。js创建一个基本的Discord机器人。当bot第一次启动时,我运行获取机器人当前订阅的所有协会的列表。我将其保存到其他程序使用的数据库中。 然而,当人们从他们的公会中添加/删除机器人时,我想保留一个更新的公会列表。我意识到我可以每分钟重新运行,但这似乎效率低下。 当你的机器人被添加到公会和/或频道时,是否有触发的事件?据我所知,事件似乎针对所有已经订阅该公会的用户/机器人

  • 如图:el-select使用文档提供的focus事件和blur事件,当focus的时候执行blur,使其失去焦点收起下拉面板。但是执行了blur事件后,触发了2次focus,想问问原因,如何解决 业务需求是:点击下拉框的时候,根据条件判断是否要展开下拉面板,不用el-select的disabled禁止,所以用以上方式实现,但是有触发2个的问题