Angular JS: IE错误:达到10次$digest()迭代。中止

27

我是Angular的新手,遇到了一个与IE有关的问题。

这是我收到的IE错误信息。

Webpage error details

User Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
Timestamp: Thu, 13 Dec 2012 04:00:46 UTC


Message: 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: [["fn: function $locationWatch() {\n      var oldUrl = $browser.url();\n\n      if (!changeCounter || oldUrl != $location.absUrl()) {\n\tchangeCounter++;\n\t$rootScope.$evalAsync(function() {\n\t  if ($rootScope.$broadcast('$locationChangeStart', $location.absUrl(), oldUrl).\n\t      defaultPrevented) {\n\t    $location.$$parse(oldUrl);\n\t  } else {\n\t    $browser.url($location.absUrl(), $location.$$replace);\n\t    $location.$$replace = false;\n\t    afterLocationChange(oldUrl);\n\t  }\n\t});\n      }\n\n      return changeCounter;\n    }; newVal: 7; oldVal: 6"],["fn: function $locationWatch() {\n      var oldUrl = $browser.url();\n\n      if (!changeCounter || oldUrl != $location.absUrl()) {\n\tchangeCounter++;\n\t$rootScope.$evalAsync(function() {\n\t  if ($rootScope.$broadcast('$locationChangeStart', $location.absUrl(), oldUrl).\n\t      defaultPrevented) {\n\t    $location.$$parse(oldUrl);\n\t  } else {\n\t    $browser.url($location.absUrl(), $location.$$replace);\n\t    $location.$$replace = false;\n\t    afterLocationChange(oldUrl);\n\t  }\n\t});\n      }\n\n      return changeCounter;\n    }; newVal: 8; oldVal: 7"],["fn: function $locationWatch() {\n      var oldUrl = $browser.url();\n\n      if (!changeCounter || oldUrl != $location.absUrl()) {\n\tchangeCounter++;\n\t$rootScope.$evalAsync(function() {\n\t  if ($rootScope.$broadcast('$locationChangeStart', $location.absUrl(), oldUrl).\n\t      defaultPrevented) {\n\t    $location.$$parse(oldUrl);\n\t  } else {\n\t    $browser.url($location.absUrl(), $location.$$replace);\n\t    $location.$$replace = false;\n\t    afterLocationChange(oldUrl);\n\t  }\n\t});\n      }\n\n      return changeCounter;\n    }; newVal: 9; oldVal: 8"],["fn: function $locationWatch() {\n      var oldUrl = $browser.url();\n\n      if (!changeCounter || oldUrl != $location.absUrl()) {\n\tchangeCounter++;\n\t$rootScope.$evalAsync(function() {\n\t  if ($rootScope.$broadcast('$locationChangeStart', $location.absUrl(), oldUrl).\n\t      defaultPrevented) {\n\t    $location.$$parse(oldUrl);\n\t  } else {\n\t    $browser.url($location.absUrl(), $location.$$replace);\n\t    $location.$$replace = false;\n\t    afterLocationChange(oldUrl);\n\t  }\n\t});\n      }\n\n      return changeCounter;\n    }; newVal: 10; oldVal: 9"],["fn: function $locationWatch() {\n      var oldUrl = $browser.url();\n\n      if (!changeCounter || oldUrl != $location.absUrl()) {\n\tchangeCounter++;\n\t$rootScope.$evalAsync(function() {\n\t  if ($rootScope.$broadcast('$locationChangeStart', $location.absUrl(), oldUrl).\n\t      defaultPrevented) {\n\t    $location.$$parse(oldUrl);\n\t  } else {\n\t    $browser.url($location.absUrl(), $location.$$replace);\n\t    $location.$$replace = false;\n\t    afterLocationChange(oldUrl);\n\t  }\n\t});\n      }\n\n      return changeCounter;\n    }; newVal: 11; oldVal: 10"]]
Line: 7859
Char: 6
Code: 0
URI: http://localhost:8080/__assets__/lib/angular/angular.js

这种情况只发生在IE 8和IE 9浏览器中,其他浏览器都没有出现过。

我有一个监视内容筛选对象的表,其中包括位置筛选器。

我的问题是为什么只有IE浏览器会出现这种情况,应该怎么做才能解决。提前感谢您的帮助。


4
你是否曾经搞清楚那个问题? - cyberwombat
7个回答

30

Tiago Roldão是对的。我也遇到了完全相同的问题。在调试后,我意识到我的代码中有:

location.hash = "#/app/" + id;

造成无限循环问题的原因。经过一些研究,我找到了这个

$location.path("/apps/" + id);

这完美地解决了我的问题。


太好了!非常感谢 :) - codingrose
非常感谢。如果没有找到这个,我就完蛋了。 - Sunil Pandey

22

我曾经遇到过一个问题,出现了一样的错误。Chrome和Firefox运行正常,但是IE无法正常工作。在我的应用程序中点击某些链接时,有时会出现这个错误,有时不会。

1)我认为我有几个看起来像这样的链接:

<a href="#" ng-click="addIP(ip)">Add some IP</a>

2) 当点击这些链接时,单击处理程序会向IpRanges集合中添加新对象,如下所示:

$scope.IpRanges.push(ip);

3) 由于使用了ng-repeat指令将集合绑定到视图上,我认为某种程度上IE无法很好地处理这种情况——可能是绑定、添加和应用事件的顺序不正确,或者其他原因......此外,在单击链接后,URL中会添加 # 符号,有时会闪烁,然后出现错误。所以我删除了href属性,一切正常工作:

<a href="" ng-click="addCurrentIP()">Add as allowed IP</a>

也许在类似的情况下使用

更好。


这是关于编程的帖子! - Dfr
嘿,非常感谢!我花了很多时间,但这解决了我的问题! - Nitu Bansal
删除整个 href 属性对我来说起作用了。 - sfs

17

当我在IE9、IE10中调用$window.history.back()时(尤其是在Windows Phone上),使用AngularJS v1.2.13时出现了相同的问题。

看起来根本原因是,IE中的$window.history.back()会在$locationWatch()触发之前更改href,因此oldUrl会包含新的URL,并将angular投入无限$digest循环。

即时的解决方法是将对$window.history.back()的调用替换为以下内容:

setTimeout(function () 
{
    $window.history.back();
}, 0);

太棒了!解决了我的问题...出于好奇 - 你是怎么想到的?我想知道你在Windows Phone上调试问题的过程是否已经建立。 - Mars Robertson
只需使用IE 11或IE10来调试网站并模拟正确的设备和文档模式,它将在99%的情况下完成。 - Aidin
它解决了我的问题。但我想知道 "setTimeout" 是如何解决这个问题的。 - Niranth Reddy
这个问题的另一个解决方案:$timeout(function () { history.go(-1); }); - Stanislav Ostapenko

5
我可以看到你的错误报告中有一个 $watch 监听了 changeCounter 变量,监听函数如下:
function $locationWatch() {
    var oldUrl = $browser.url();
    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(), $location.$$replace);
                $location.$$replace = false;
                afterLocationChange(oldUrl);
            }
        });
    }
    return changeCounter;
};

如果 $browser.url() 不等于 $location.absUrl(),则 changeCounter 的值会被增加。由于 $watch 函数只能进行 10 次循环的更改/反应,所以在这些 10 次迭代后会发生错误。因为你正在更改你正在观察的值,所以它最终会崩溃。

我会记录这些值 - $location.absUrl() 和 $browser.url(),并查看为什么在其他浏览器中匹配,但在 IE 中不匹配。


1
感谢您的回复,Tiago。但我必须告诉你,这不是我编写的函数。它是angular.js提供的库函数。 - Abilash
这也被AngularJS所监视。 - Abilash

3

我在使用IE 10时遇到了问题。

我正在使用:

window.location.href = '#/';

为更改路由。 将其替换为以下代码。
$location.path('/');

解决了问题。

2

简述

如果您正在使用ui-router,那么您也可以使用以下内容:

$state.go('details', {id:item.ID});

背景

我正在使用以下函数来从列表视图导航到详细视图,以便您可以点击列表中的任何内容ng-click="details(item)",在我的情况下是列表中的tr

$scope.details = function (item) {
    $window.location.href = "#/details/" + item.ID;
}

但是我在IE浏览器中遇到了可怕的10 $digest() iterations reached错误。

顺便提一下

我按照Tiago的回答,在AngularJS v1.2.0rc1 angular.js的7650行设置了一个断点。

// update browser
var changeCounter = 0;
$rootScope.$watch(function $locationWatch() {
  var oldUrl = $browser.url();
  var currentReplace = $location.$$replace;

  if (!changeCounter || oldUrl != $location.absUrl()) {
    changeCounter++; /* <-- breakpoint here, line 7650 */
    $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;
});

结果

来自Chrome的输出

  • 只有在详情页面加载时,断点才会被命中,并且只命中一次。
  • oldUrl(即$browser.url())报告旧的URL(即列表页)。
  • $location.absUrl()报告详情URL。

来自IE7,8的输出

  • 断点持续被命中。
  • oldUrl(即$browser.url())报告新的URL(即详情页)。
  • $location.absUrl()仍然报告列表URL。

0

当我尝试重定向到其他页面时,我遇到了这个问题。

$window.location.href = '#/path/'

通过更改为以下内容解决:

$location.path('/path/');

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