可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm new to Angular and I'm stuck with a issue relating IE.
Here is the IE Error that I'm getting.
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
This is not happening in any other browser but IE 8 and IE 9.
I have a watch looking at a content filtering object which includes a location filter.
My question with this is why doesn't it happen on any other browser but IE and what should I do to get rid of this. Thanks in advance.
回答1:
I had the same issue with error which looked the same. Chrome\FF worked fine, but IE failed. I've clicked on some links in my app and sometimes got this error and sometimes not.
1) In my view I had few links which looked like this:
<a href="#" ng-click="addIP(ip)">Add some IP</a>
2) Click handler for those links added new object into IpRanges collection like this:
$scope.IpRanges.push(ip);
3) Collection itself was binded on view by ng-repeat, and I thought that somehow IE could not handle this situation well - probably order of binding\adding\applying events wasn't incorrect or else... Also after click on links I had # symbol added to url, and sometimes it blinked, and then I've got an error. So I removed href attribute and everything worked fine:
<a href="" ng-click="addCurrentIP()">Add as allowed IP</a>
Probably it's better to use spans or divs for similar situations.
回答2:
location.hash = "#/app/" + id;
which causes the infinitely loop issue. After some research, I found this
$location.path("/apps/" + id);
which solves my issue perfectly.
回答3:
I had the same issue using AngularJS v1.2.13 in IE9, IE10, when calling $window.history.back() (especially in Windows Phone).
It seems the root cause is that $window.history.back() in IE changes the href right before the $locationWatch() is fired hence oldUrl would contain the new Url and that throws off the angular into an infinite $digest.
The immediate work around is to replace the calls to $window.history.back() with the following:
setTimeout(function () { $window.history.back(); }, 0);
回答4:
I can tell from your error report you have a $watch for a changeCounter variable, and this watcher function:
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; };
And the changeCounter gets it's value incremented if $browser.url() doesn't equal $location.absUrl(). As the $watch function can only do 10 loops of change/reaction, it will err after those 10 iterations. As you are changing the value you are watching, it eventually breaks.
I would log those values - $location.absUrl() and $browser.url(), and see why the match in other browsers, but not in ie.
回答5:
TLDR
If you are using ui-router
then you can also use
$state.go('details', {id:item.ID});
Background
I was using the following function to navigate from a list view to a details view so that you can click anything with ng-click="details(item)"
, in my case tr
's in the list:
$scope.details = function (item) { $window.location.href = "#/details/" + item.ID; }
But I was getting the dreaded 10 $digest() iterations reached
in IE.
FYI
I placed a breakpoint in AngularJS v1.2.0rc1 angular.js line 7650 following Tiago's answer.
// 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; });
Results
Output from Chrome
- The breakpoint was only hit once the details page was loading and once only.
oldUrl
(i.e. $browser.url()
was reporting the old url (i.e. the list one) $location.absUrl()
was reporting the details url.
Output from IE7,8
- The breakpoint was hit continuously.
oldUrl
(i.e. $browser.url()
was reporting the new url (i.e. the details one) $location.absUrl()
was still reporting the list url.
回答6:
I was facing issue in IE 10. I was using
window.location.href = '#/';
for changing the route. Replacing it with below code
$location.path('/');
resolved the issue
回答7:
I had this problem when trying to redirect to other page as
$window.location.href = '#/path/'
solved by changing to:
$location.path('/path/');