如何修复“超出最大调用堆栈大小"AngularJS [英] How can I fix 'Maximum call stack size exceeded' AngularJS

查看:19
本文介绍了如何修复“超出最大调用堆栈大小"AngularJS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 AngularJs 和 Ui-Router,我正在尝试设置两个不同的主页,一个用于已登录的用户,另一个用于未登录的用户.但我收到以下错误:

RangeError:超出最大调用堆栈大小

我运行了 console.trace() 并且我可以看到有一个问题导致状态无限循环(或类似的).但是我不知道如何解决它.

这是产生错误的代码.

.run(function ($rootScope, $state, $location, Auth) {$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState) {if(fromState.name === "") {如果(Auth.isLoggedIn()){$state.go('main');event.preventDefault();} 别的 {$state.go('欢迎');event.preventDefault();}} 别的 {如果 (toState.authenticate && !Auth.isLoggedIn()) {$location.path('/登录');event.preventDefault();}}});

据我所知,它似乎源于 if(fromState.name === "")

解决方案

我已经创建了 an示例,使用默认页面和 auth/unauth 用户.类似的问题可以在这里

看到

首先这将是侦听器:

app.run(function ($rootScope, $state, $location, Auth) {$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState) {var shouldLogin = toState.data !== undefined&&toState.data.requireLogin&&!Auth.isLoggedIn ;//未通过身份验证 - 想要任何私密的东西如果(应该登录){$state.go('登录');event.preventDefault();返回;}//已认证(以前)不来自 root main如果(Auth.isLoggedIn){var shouldGoToMain = fromState.name === ""&&toState.name !== "main" ;如果 (shouldGoToMain){$state.go('main');event.preventDefault();}返回;}//未经身份验证的(以前)不会进入 root 公共var shouldGoToPublic = fromState.name === ""&&toState.name !== "public"&&toState.name !== "登录" ;if(shouldGoToPublic){$state.go('public');console.log('p')event.preventDefault();}//非托管});});

发生了什么?

  • 我们检查用户是否已登录.如果没有,但需要访问非公开内容...我们重定向到登录
  • 用户已登录但未直接进入主界面...我们将他转移
  • 用户未登录,但未公开......我们重定向
  • 否则...顺其自然

这里是状​​态:

 $stateProvider//任何人都可以使用.state('公共',{网址:'/公共',模板:'<div>public</div>',})//仅用于认证.state('主要',{网址:'/主要',模板:'

main 用于已验证的

',数据:{requireLogin:true},})//仅用于认证.state('其他',{网址:'/其他',模板 : '

other for authentication

',数据:{requireLogin:true},})//登录界面.state('登录',{网址:'/登录',templateUrl : 'tpl.login.html',控制器:'登录Ctrl',})

检查 plunker here这里

I am using AngularJs and Ui-Router and I am trying to set two different home pages, one for users that are logged in and the other for users that aren't. But I am getting the following error:

RangeError: Maximum call stack size exceeded

I ran console.trace() and I can see that there is an issue which is causing the states to loop infinitely (or something like that). BUt I have no idea how to fix it.

Here is the code that is generating the error.

.run(function ($rootScope, $state, $location, Auth) {
    $rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState) {
      if(fromState.name === "") {
        if (Auth.isLoggedIn()) {
            $state.go('main');
            event.preventDefault();
        } else {
          $state.go('welcome');
          event.preventDefault();
        }
      } else {
         if (toState.authenticate && !Auth.isLoggedIn()) {
             $location.path('/login');
             event.preventDefault();
         }
      }
    });

From what I can tell it seems to stem from if(fromState.name === "")

解决方案

I've created an example, playing with default pages and auth/unauth user. Similar issue could be seen here

Firstly this would be the listener:

app.run(function ($rootScope, $state, $location, Auth) {

    $rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState) {

      var shouldLogin = toState.data !== undefined
                    && toState.data.requireLogin 
                    && !Auth.isLoggedIn ;

      // NOT authenticated - wants any private stuff
      if(shouldLogin)
      {
        $state.go('login');
        event.preventDefault();
        return;
      }


      // authenticated (previously) comming not to root main
      if(Auth.isLoggedIn) 
      {
        var shouldGoToMain = fromState.name === ""
                          && toState.name !== "main" ;

        if (shouldGoToMain)
        {
            $state.go('main');
            event.preventDefault();
        } 
        return;
      }

      // UNauthenticated (previously) comming not to root public 
      var shouldGoToPublic = fromState.name === ""
                        && toState.name !== "public"
                        && toState.name !== "login" ;

      if(shouldGoToPublic)
      {
          $state.go('public');console.log('p')
          event.preventDefault();
      } 

      // unmanaged
    });
});

What is happening?

  • We check if user is logged in. If not, but requires access to not public stuff... we redirect to login
  • user is logged in but not going directly to main... we transfer him
  • user is not logged in, but not going to public ... we redirect
  • else... let it be

And here are states:

  $stateProvider
    // available for anybody
    .state('public',{
        url : '/public',
        template : '<div>public</div>',
    })
    // just for authenticated
    .state('main',{
        url : '/main',
        template : '<div>main for authenticated</div>',
        data : {requireLogin : true },
    })
    // just for authenticated
    .state('other',{
        url : '/other',
        template : '<div>other for authenticated</div>',
        data : {requireLogin : true },
    })
    // the log-on screen
    .state('login',{
        url : '/login',
        templateUrl : 'tpl.login.html',
        controller : 'LoginCtrl',
    })

Check plunker here or here

这篇关于如何修复“超出最大调用堆栈大小"AngularJS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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