Angular JS: Ошибка IE: Достигнуты истребители 10 $digest(). Aborting
Я новичок в 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, и что мне делать, чтобы избавиться от этого. Спасибо заранее.
Ответы
Ответ 1
У меня была такая же проблема с ошибкой, которая выглядела одинаково. Chrome\FF работал нормально, но 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>
Возможно, лучше использовать интервалы или div для подобных ситуаций.
Ответ 2
Тьяго Ролдао определенно прав. У меня была точно такая же проблема. После отладки я понял в своем коде, что у меня
location.hash = "#/app/" + id;
что вызывает бесконечную проблему цикла. После некоторых исследований я нашел это
$location.path("/apps/" + id);
который отлично решает мою проблему.
Ответ 3
У меня была такая же проблема с использованием AngularJS v1.2.13 в IE9, IE10 при вызове $window.history.back() (особенно в Windows Phone).
Похоже, первопричина заключается в том, что $window.history.back() в IE меняет href прямо перед запуском $locationWatch(), поэтому oldUrl будет содержать новый Url и отбрасывает angular в бесконечный $дайджеста.
Непосредственная работа заключается в замене вызовов на $window.history.back() следующим образом:
setTimeout(function ()
{
$window.history.back();
}, 0);
Ответ 4
Я могу сказать, что из вашего отчета об ошибке у вас есть $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;
};
И changeCounter получает значение value incremented, если $browser.url() не равно $location.absUrl(). Поскольку функция $watch может выполнять только 10 циклов изменения/реакции, она будет ошибаться после этих 10 итераций. Когда вы меняете значение, которое вы смотрите, оно в конечном итоге ломается.
Я бы зарегистрировал эти значения - $location.absUrl() и $browser.url() и посмотрел, почему совпадение в других браузерах, но не в ie.
Ответ 5
TL;DR
Если вы используете ui-router
, вы также можете использовать
$state.go('details', {id:item.ID});
Фон
Я использовал следующую функцию для перехода от представления списка к представлению деталей, чтобы вы могли щелкнуть все с помощью ng-click="details(item)"
, в моем случае tr
в списке:
$scope.details = function (item) {
$window.location.href = "#/details/" + item.ID;
}
Но я получал страшный 10 $digest() iterations reached
в IE.
FYI
Я поставил точку останова в строке 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-адрес списка.
Ответ 6
Я столкнулся с проблемой в IE 10.
Я использовал
window.location.href = '#/';
для изменения маршрута.
Заменяя его
ниже кода
$location.path('/');
разрешил проблему
Ответ 7
У меня была эта проблема при попытке перенаправления на другую страницу как
$window.location.href = '#/path/'
решив изменить на:
$location.path('/path/');