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

时间:2012-12-13 05:57:37

标签: javascript angularjs

我是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上的任何其他浏览器上,我应该怎么做才能摆脱这个。提前谢谢。

7 个答案:

答案 0 :(得分:29)

TiagoRoldão绝对是对的。我有同样的问题。调试后,我在我的代码中实现了

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

导致无限循环问题。经过一番研究,我找到了这个

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

完美地解决了我的问题。

答案 1 :(得分:22)

我遇到了同样的错误问题。 Chrome \ FF工作正常,但IE失败了。我点击了我的应用中的一些链接,有时会出现此错误,有时不会。

1)在我看来,我的链接看起来像这样:

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

2)点击这些链接的处理程序,将新对象添加到IpRanges集合中,如下所示:

$scope.IpRanges.push(ip);

3)集合本身在ng-repeat上被绑定在视图中,我认为IE不能很好地处理这种情况 - 可能是绑定\添加\应用事件的顺序不正确或者其他...也是点击后在链接上我有#符号添加到网址,有时它眨眼,然后我有一个错误。所以我删除了href属性,一切正常:

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

对于类似的情况,最好使用跨度或div。

答案 2 :(得分:17)

在调用$ window.history.back()时,在IE9,IE10中使用AngularJS v1.2.13时遇到了同样的问题。(特别是在Windows Phone中)。

似乎根本原因是IE中的$ window.history.back()在$ locationWatch()被触发之前改变了href,因此oldUrl将包含新的Url并且将角度抛出到无限$ digest中

立即解决的问题是使用以下内容替换对$ window.history.back()的调用:

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

答案 3 :(得分:5)

我可以从你的错误报告中看出你有一个$ watch for 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。

答案 4 :(得分:2)

TLDR

如果您使用的是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

FYI

在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()报告旧网址(即列表一)
  • $location.absUrl()报告了详细信息网址。

IE7,8的输出

  • 断点不断被击中。
  • oldUrl(即$browser.url()报告了新网址(即详细信息)
  • $location.absUrl()仍在报告列表网址。

答案 5 :(得分:2)

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

window.location.href = '#/';

用于更改路线。 用它替换它  下面的代码

$location.path('/');

解决了问题

答案 6 :(得分:0)

尝试重定向到其他网页时遇到此问题

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

通过改为:

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