как сказал Вен, вы либо возвращаете разные (не идентичные) объекты в каждом $digest
цикле, либо изменяете данные слишком много раз.
Самое быстрое решение, чтобы выяснить, какая часть вашего приложения вызывает такое поведение:
- удалите весь подозрительный HTML - в основном удалите весь свой html из шаблона и проверьте, нет ли предупреждений
- если нет предупреждений - добавьте небольшие части удаленного html и проверьте, вернулась ли проблема
- повторяйте шаг 2, пока не получите предупреждение - вы выясните, какая часть вашего html отвечает за проблему
- исследуйте дальше - часть из шага 3 отвечает либо за изменение объектов на,
$scope
либо возвращает неидентичные объекты в каждом $digest
цикле.
- если
$digest
после шага 1 у вас все еще появляются предупреждения о повторении, то вы, вероятно, делаете что-то очень подозрительное. Повторите те же шаги для родительского шаблона / области действия / контроллера.
Вы также хотите убедиться, что не изменяете ввод своих пользовательских фильтров.
Имейте в виду, что в JavaScript есть определенные типы объектов, которые ведут себя не так, как вы обычно ожидаете:
new Boolean(true) === new Boolean(true) // false
new Date(0) == new Date(0) // false
new String('a') == new String('a') // false
new Number(1) == new Number(1) // false
[] == [] // false
new Array == new Array // false
({})==({}) // false
map()
иgroupBy()
убедитесь, что ваши$watch
es выполняют грязную проверку,objectEquality
$watch('myFunctionDoingGropby',callback,true)
см. Docs.angularjs.org/api/ng.$rootScope.Scope#$watch$scope
которой_.map
один раз назначается список -ed, но в общем случае, как бы вы повлияли на указанную грязную проверку равенством объектов, если это не созданный вручную,$watch
который отключается, ноngRepeat
?Обычно это происходит, когда вы каждый раз возвращаете другой объект.
Например, если вы используете это в
ng-repeat
:$scope.getObj = function () { return [{a: 1}, {b: 2}]; };
Вы получите это сообщение об ошибке, потому что Angular пытается добиться «стабильности» и будет выполнять функцию, пока она не вернет тот же результат 2 раза (по сравнению с
===
), который в нашем случае никогда не вернет true, потому что функция всегда возвращает новый объект.console.log({} === {}); // false. Those are two different objects!
В этом случае вы можете исправить это, сохранив объект напрямую в области видимости, например
$scope.objData = [{a: 1}, {b: 2}]; $scope.getObj = function () { return $scope.objData; };
Таким образом вы всегда возвращаете один и тот же объект!
console.log($scope.objData === $scope.objData); // true (a bit obvious...)
(Вы никогда не должны сталкиваться с этим, даже в сложных приложениях).
Обновление: Angular добавил на свой сайт более подробное объяснение .
источник
Просто хотел добавить сюда это решение, надеюсь, оно поможет другим. У меня возникла эта проблема с итерацией, потому что я перебирал сгенерированное свойство, которое создавало новый объект при каждом его вызове.
Я исправил это, кэшируя сгенерированный объект при первом запросе, а затем всегда возвращая кеш, если он существует. Также был добавлен метод dirty (), который при необходимости уничтожал кешированные результаты.
У меня было примерно так:
function MyObj() { var myObj = this; Object.defineProperty(myObj, "computedProperty" { get: function () { var retObj = {}; return retObj; } }); }
И вот с реализованным решением:
function MyObj() { var myObj = this, _cached; Object.defineProperty(myObj, "computedProperty" { get: function () { if ( !_cached ) { _cached = {}; } return _cached; } }); myObj.dirty = function () { _cached = null; } }
источник
Также существует вероятность того, что это вообще не бесконечный цикл. 10 итераций - это недостаточно большое количество, чтобы сделать такой вывод с какой-либо степенью уверенности. Поэтому перед тем, как отправиться в погоню за диким гусем, рекомендуется сначала исключить такую возможность.
Самый простой способ сделать это - увеличить максимальное количество циклов дайджеста до гораздо большего числа, что можно сделать в
module.config
методе, используя$rootScopeProvider.digestTtl(limit)
метод. Еслиinfdig
ошибка больше не появляется, у вас просто есть достаточно сложная логика обновления.Если вы создаете данные или представления, основанные на рекурсивных наблюдениях, вы можете искать итеративные решения (т.е. не полагаться на запуск новых циклов дайджеста), используя
while
,for
илиArray.forEach
. Иногда структура просто сильно вложена и даже не рекурсивна, в таких случаях, вероятно, нечего делать, кроме увеличения лимита.Другой метод отладки ошибки - просмотр данных дайджеста. Если вы распечатаете JSON, вы получите массив массивов. Каждая запись верхнего уровня представляет собой итерацию, каждая итерация состоит из списка отслеживаемых записей.
Если у вас, например, есть свойство, которое изменяется
$watch
само по себе, легко увидеть, что значение изменяется бесконечно:$scope.vm.value1 = true; $scope.$watch("vm.value1", function(newValue) { $scope.vm.value1 = !newValue; });
[ [ { "msg":"vm.value1", "newVal":true, "oldVal":false } ], [ { "msg":"vm.value1", "newVal":false, "oldVal":true } ], [ { "msg":"vm.value1", "newVal":true, "oldVal":false } ], [ { "msg":"vm.value1", "newVal":false, "oldVal":true } ], [ { "msg":"vm.value1", "newVal":true, "oldVal":false } ] ]
Конечно, в более крупном проекте это может быть не так просто, тем более что
msg
поле часто имеет значение"fn: regularInterceptedExpression"
если часы являются{{ }}
интерполяцией.Помимо этого, уже упомянутые методы, такие как сокращение HTML для поиска источника проблемы, конечно же, полезны.
источник
У меня была та же проблема - я каждый раз создавал новую дату. Итак, для всех, кто имеет дело с датами, я преобразовал все вызовы следующим образом:
var date = new Date(); // typeof returns object
кому:
var date = new Date().getTime(); // typeof returns number
Инициализация числа вместо объекта даты решила эту проблему для меня.
источник
простой способ: используйте angular.js, а не файл min. откройте его и найдите строку:
if ((dirty || asyncQueue.length) && !(ttl--)) {
добавьте строку ниже:
console.log("aaaa",watch)
а затем обновите свою страницу, в консоли инструментов разработки вы найдете код ошибки.
источник
Это известная ошибка
ui-router
, нам это помогло: https://github.com/angular-ui/ui-router/issues/600источник
Я также хотел бы отметить, что я получил это сообщение об ошибке, когда у меня была опечатка в templateUrl настраиваемой директивы, которая была у меня в моем проекте. Из-за опечатки не удалось загрузить шаблон.
/* @ngInject */ function topNav() { var directive = { bindToController: true, controller: TopNavController, controllerAs: 'vm', restrict: 'EA', scope: { 'navline': '=', 'sign': '=' }, templateUrl: 'app/shared/layout/top-navTHIS-IS-A-TYPO.html' };
Посмотрите на вкладку сети инструментов разработчика вашего веб-браузера и посмотрите, есть ли на каком-либо ресурсе ошибка 404.
Легко не заметить, потому что сообщение об ошибке очень загадочное и, по-видимому, не связано с реальной проблемой.
источник
У меня была эта проблема в моем проекте, потому что .otherwise () не хватало моего определения маршрута, и я выбирал неправильный маршрут.
источник
У меня была эта проблема, потому что я делал это
var variableExpense = this.lodash.find(product.variableExpenseList, (ve) => { return ve.rawMaterial.id = rawMaterial.id; });
Вместо этого: (notice = vs ===) мой модульный тест начал ломаться, и я обнаружил свою глупость
var variableExpense = this.lodash.find(product.variableExpenseList, (ve) => { return ve.rawMaterial.id === rawMaterial.id; });
источник
Я столкнулся с этой проблемой, когда мне нужна была динамическая всплывающая подсказка ... это заставляло angular пересчитывать его каждый раз как новое значение (хотя оно было таким же). Я создал функцию для кеширования вычисленного значения следующим образом:
$ctrl.myObj = { Title: 'my title', A: 'first part of dynamic toolip', B: 'second part of dynamic tooltip', C: 'some other value', getTooltip: function () { // cache the tooltip var obj = this; var tooltip = '<strong>A: </strong>' + obj.A + '<br><strong>B: </strong>' + obj.B; var $tooltip = { raw: tooltip, trusted: $sce.trustAsHtml(tooltip) }; if (!obj.$tooltip) obj.$tooltip = $tooltip; else if (obj.$tooltip.raw !== tooltip) obj.$tooltip = $tooltip; return obj.$tooltip; } };
Затем в html я получил доступ к нему так:
<input type="text" ng-model="$ctrl.myObj.C" uib-tooltip-html="$ctrl.myObj.getTooltip().trusted">
источник
вот как я подошел к этому и нашел решение: я проверил текст, он показал:
Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Наблюдатели, запущенные в последних 5 итерациях: [[{"msg": "statement === statment && functionCall ()", "newVal": [{"id": 7287, "referen ...
так что если вы можете увидеть
это состояние, вызывающее ошибку. Я проверил функцию, вызываемую в этом сообщении, я вернул (false) от всех из них, просто чтобы определить, у кого из них проблема. один из них вызывал функцию, которая постоянно меняет результат, что является проблемой.
источник
Как бы безумно это ни звучало, я исправил эту ошибку, просто перезапустив браузер, когда она внезапно возникла.
Итак, одно из решений - просто очистить кеш браузера или попробовать перезапустить браузер.
источник