【问题标题】:How can I fix 'Maximum call stack size exceeded' AngularJS如何修复“超出最大调用堆栈大小”AngularJS
【发布时间】:2014-07-30 04:05:41
【问题描述】:

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

RangeError: Maximum call stack size exceeded

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

这是产生错误的代码。

.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();
         }
      }
    });

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

【问题讨论】:

  • 你的循环在哪里。当循环运行不定式时,会发生此错误
  • 对不起,我不是说我有一个“循环”,我的意思是更多的错误是循环的,或者 state.go 可能是循环的。我已经更新了这个问题,希望它更清楚一点。
  • 确保您没有更改$state.go 中的$rootScope 变量,这可能是原因,但通常会导致无限的$digest 错误。这是一个奇怪的错误,最好尝试在 plunkr 中复制它,通常我发现尝试在我的环境之外复制它的过程有助于找出问题所在。对于奇怪的问题,工作示例也更清晰!
  • 我实际上不知道如何在 plunkr 上设置它以进行复制,我正在使用 angular-fullstack,其中包括 express 和 mongo 我无法让身份验证与其余部分一起工作的应用程序。所以我不能举一个会引发错误的公平例子。

标签: javascript angularjs angular-ui-router


【解决方案1】:

我创建了an example,使用默认页面和 auth/unauth 用户。类似问题可见here

首先这是监听器:

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

发生了什么?

  • 我们检查用户是否登录。如果没有,但需要访问不公开的东西...我们重定向到登录
  • 用户已登录但未直接进入主...我们转移他
  • 用户未登录,但未公开...我们重定向
  • 否则……就这样吧

这里是状​​态:

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

检查plunker herehere

【讨论】:

    【解决方案2】:

    使用 $state.go("main", {}, {notify:false});不通知“$stateChangeStart”事件。

      // NOT authenticated - wants any private stuff
      if(shouldLogin)
      {
        $state.go("main", {}, {notify:false});
        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", {}, {notify:false});
            event.preventDefault();
        } 
        return;
      }
    

    【讨论】:

    • 这个解决方案在我看来要简单得多。它也很完美。
    猜你喜欢
    • 1970-01-01
    • 2019-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-12
    • 1970-01-01
    • 2015-10-24
    • 2015-12-29
    相关资源
    最近更新 更多