SCRIPT5022: 10次$digest()迭代已达到。中止操作!并重定向到index.html。

6

问题:

我尝试在bootstrap模态框中加载一个Angular JS应用,但在Internet Explorer上显示出奇怪的行为(我们已经在IE9和8上测试过)。

我们发现我们遇到了以下错误:

** 'JSON'未定义 **对象错误未定义

SCRIPT5022: 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: [["fn: function $locationWatch() {
  var oldUrl = $browser.url();
  var currentReplace = $location.$$replace;

  if (!changeCounter || oldUrl != $location.absUrl()) {
    changeCounter++;
    $rootScope.$evalAsync(function() {
      if ($rootScope.$broadcast('$locationChangeStart', $location.absUrl(), oldUrl).
          defaultPrevented) {
        $location.$$parse(oldUrl);
      } else {
        $browser.url($location.absUrl(), currentReplace);
        afterLocationChange(oldUrl);
      }
    });
  }
  $location.$$replace = false;

  return changeCounter;
}; newVal: 7; oldVal: 6"],["fn: function $locationWatch() {
  var oldUrl = $browser.url();
  var currentReplace = $location.$$replace;

  if (!changeCounter || oldUrl != $location.absUrl()) {
    changeCounter++;
    $rootScope.$evalAsync(function() {
      if ($rootScope.$broadcast('$locationChangeStart', $location.absUrl(), oldUrl).
          defaultPrevented) {
        $location.$$parse(oldUrl);
      } else {
        $browser.url($location.absUrl(), currentReplace);
        afterLocationChange(oldUrl);
      }
    });
  }
  $location.$$replace = false;

  return changeCounter;
}; newVal: 8; oldVal: 7"],["fn: function $locationWatch() {
  var oldUrl = $browser.url();
  var currentReplace = $location.$$replace;

  if (!changeCounter || oldUrl != $location.absUrl()) {
    changeCounter++;
    $rootScope.$evalAsync(function() {
      if ($rootScope.$broadcast('$locationChangeStart', $location.absUrl(), oldUrl).
          defaultPrevented) {
        $location.$$parse(oldUrl);
      } else {
        $browser.url($location.absUrl(), currentReplace);
        afterLocationChange(oldUrl);
      }
    });
  }
  $location.$$replace = false;

  return changeCounter;
}; newVal: 9; oldVal: 8"],["fn: function $locationWatch() {
  var oldUrl = $browser.url();
  var currentReplace = $location.$$replace;

  if (!changeCounter || oldUrl != $location.absUrl()) {
    changeCounter++;
    $rootScope.$evalAsync(function() {
      if ($rootScope.$broadcast('$locationChangeStart', $location.absUrl(), oldUrl).
          defaultPrevented) {
        $location.$$parse(oldUrl);
      } else {
        $browser.url($location.absUrl(), currentReplace);
        afterLocationChange(oldUrl);
      }
    });
  }
  $location.$$replace = false;

  return changeCounter;
}; newVal: 10; oldVal: 9"],["fn: function $locationWatch() {
  var oldUrl = $browser.url();
  var currentReplace = $location.$$replace;

  if (!changeCounter || oldUrl != $location.absUrl()) {
    changeCounter++;
    $rootScope.$evalAsync(function() {
      if ($rootScope.$broadcast('$locationChangeStart', $location.absUrl(), oldUrl).
          defaultPrevented) {
        $location.$$parse(oldUrl);
      } else {
        $browser.url($location.absUrl(), currentReplace);
        afterLocationChange(oldUrl);
      }
    });
  }
  $location.$$replace = false;

  return changeCounter;
}; newVal: 11; oldVal: 10"]]

我们发现IE浏览器有3个问题:

  1. JSON不可用
  2. 引导应用程序存在问题
  3. 视图渲染存在问题

通过查阅Angular JS文档和StackOverflow的许多主题,例如:

我们发现所有主题都有一些共同点(也在AngulaJS IE指南中提到): * 为IE包括JSON2 / JSON3 pollyfills * 使用ie-shiv,并预声明自定义标记(我们使用自定义的typeahead指令,restrict:'E',replace:true) * 使用其他IE特定的说明

因此,我进行了以下更改:

var markup = '<div id="ng-app" class="ng-app:myapp" ng-app="myapp" xmlns:ng="http://angularjs.org"><div ng-controller="MyAppAppCtrl"><div ng-view></div></div></div>';
    jQuery('#works-modal').html(markup);
    angular.bootstrap(jQuery('#ng-app'), ['myapp']);   
    jQuery('#works-modal').modal('show');

实施上述更改后,我仍然遇到了以下问题:
Error: 10 $digest() iterations reached. Aborting!

https://github.com/angular/angular.js/issues/1417

尝试渲染视图时,应用程序会重定向到主页。因此,我尝试按照以下建议进行更改:

https://github.com/RobbinHabermehl/angular.js/commit/c801f91a25b9be6f5b1163c012e63c84cc6a1359

现在,当我单击链接以显示模态对话框时,不再出现错误,它会显示弹出窗口一秒钟,然后重定向到主页。

如果我设置:

$locationProvider.html5Mode(false)
  .hashPrefix('!');

它正常工作。有人遇到类似的问题吗?任何帮助都将不胜感激。

更新 我还在Angular JS Github bug列表上报告了这个问题,他们告诉我他们已经在1.2版本上修复了这个问题:

https://github.com/angular/angular.js/issues/3397

如果这能解决我的问题,我会检查并更新这个线程。

更新

我更新了我的Angular版本,这似乎解决了这个"10 $digest() iterations reached. Aborting!",但是它仍然似乎触发了URL更改,导致它重定向到主页。

让我在这里解释一下我的情况,这样其他人就可以建议我是否与此完全相关:

我有一个页面,比如:http://example.com/users/myCollection.html 在这个页面上,我在Bootstrap模态对话框中加载了我的AngularJS应用程序,当用户单击页面上的某个链接时,加载在Modal中的应用程序的Angular路由为:/mywork/find

在提高Angular版本之后,现在,模态似乎会加载应用程序一秒钟,然后发生重定向,并转到主页。

FYI,我还在页面上使用jQuery来启动Angular App,这会不会有冲突的可能性?

谢谢, Ravish


"JSON undefined" 在 IE8+ 中表示页面正在以怪异模式运行。在标准模式下,JSON 全局变量是可用的。错误的渲染模式可能会导致渲染问题和其他一些问题。 - Tomalak
好的,我已经解决了“JSON未定义”的问题。由于某些兼容性原因,我们正在使用“EmulateIE7”。 - Ravish
我正在使用 Hogan Engine,如果有帮助的话。我设置了 html5mode(false),并添加了一些 console.log 来查看我的控制器是否被多次调用,结果它被调用了两次,但是当 html5mode(false) 时视图仍然被渲染了。 - Ravish
1
@Tomalak 是的,那是个好主意,我想我会添加一个回答描述我如何解决 10 $digest() 错误,这可能会帮助某个人... - Ravish
如果有足够的人遇到您的答案:一旦您对此达到+3,您甚至可以获得[自学者]徽章。 ;) - Tomalak
显示剩余2条评论
1个回答

9

我已经总结了我的问题以及我采取的步骤来解决这些问题,让我再次总结一下,然后我将总结与“10 $digest() iterations reached. Aborting!”相关的问题:

第一步)在IE上引导应用程序的问题

在IE上引导应用程序的问题。我们在Bootstrap模态对话框中加载我们的Angular App,并手动引导Angular App。由于我们遇到了错误渲染视图,我们怀疑它要么是因为我们漏掉了IE不喜欢的某些东西,要么是因为它根本不喜欢我的自定义指令或Hogan引擎,我们正在使用我们的自定义指令。我通过阅读特定的Angular JS文档和一个Stackoverflow线程来解决它们。

我强烈建议每个人都遵循以下方法,工作或将要使用Angular JS,请阅读以下内容:

第二步)

经过第一步,我们能够使用html5mode(false)运行应用程序,但是,html5mode(true)对我们仍然是一个问题。经过一些调试和添加几个console.log,我们意识到即使使用html5mode(false),应用程序也会被引导两次。两次?但是,我们正在手动引导应用程序。 以下是我引导Angular app的模板:

var markup = '<div id="ng-app" class="ng-app:myapp" ng-app="myapp" xmlns:ng="http://angularjs.org"><div ng-controller="MyAppAppCtrl"><div ng-view></div></div></div>';
jQuery('#works-modal').html(markup);
angular.bootstrap(jQuery('#ng-app'), ['myapp']);   
jQuery('#works-modal').modal('show');

我们修改了上述模板,类似于:
var markup = '<div id="ng-app" ng-app="myapp" xmlns:ng="http://angularjs.org"><div ng-controller="MyAppAppCtrl"><div ng-view></div></div></div>';
jQuery('#works-modal').html(markup);
angular.bootstrap(jQuery('#ng-app'), ['myapp']);   
jQuery('#works-modal').modal('show');

在启动应用程序的链接上添加了"onclick="return false;" href="#"。

注意:如果您的应用程序中有超链接,请确保正确处理它们,并且它们正在执行您想要的操作,因为"href"可能导致位置更改,这可能不受您的应用程序欢迎。

步骤3)更新版的Angular JS

某些Angular JS Github bug页面中提到了几种可能的修复方法:

其中一种解决方法在以下Gist中提到:https://github.com/RobbinHabermehl/angular.js/commit/c801f91a25b9be6f5b1163c012e63c84cc6a1359

然而,我对修补核心库的想法并不感到舒适,更新核心库有其自己的缺点,即您可能需要重新设计应用程序使用的库的一部分代码,因为库已被弃用,但是,如果有重要的错误修复(像我们面临的问题的修复)和改进,则总是可以继续的。所以,我们将迁移到Angular JS的最新稳定版本。

现在,我们不再遇到此错误,并且能够在所有浏览器上引导我们的应用程序(是的,甚至在OMG IE7上;))。

一切都好了,对吧? 好吧,在提升Angular版本后,现在模态似乎会加载应用程序一秒钟,然后进行重定向,并转到主页。

然而,Angular JS $location服务指南($location服务配置和Hashbang和HTML5 Modes),在这里解释了这个问题:http://code.angularjs.org/1.2.14/docs/guide/dev_guide.services.$location

HashBang(或HTML5回退模式)需要服务器端配置,这是一种服务器端“hack”。这完全取决于您是否“真正”需要像这样的东西。

所以,现在一切都好了 :)

希望对正在解决此类问题或类似问题的任何人有所帮助。

再次强调,Angular JS非常好 ;)


1
这是一个自问自答问题的典范回答。保持下去,因为大多数人不会费心解释他们自己的解决方案。加一。 - Tomalak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接