ejemplos - angularjs pdf
Cómo solucionar problemas Angular "10 $ digest() iteraciones alcanzadas" Error (12)
Es un error conocido en ui-router
, esto nos ayudó: https://github.com/angular-ui/ui-router/issues/600
10 iteraciones de $ digest () alcanzadas. Aborto!
Hay un montón de texto de apoyo en el sentido de "Vigilantes disparados en las últimas 5 iteraciones", etc., pero gran parte de este texto es un código Javascript de varias funciones. ¿Hay reglas generales para diagnosticar este problema? ¿Es un problema SIEMPRE mitigado, o hay aplicaciones lo suficientemente complejas como para que este problema se deba tratar como una simple advertencia?
Estaba teniendo este problema en mi proyecto porque .otherwise () me faltaba la definición de mi ruta y estaba llegando a la ruta incorrecta.
Me encontré con este problema en el que necesitaba una información sobre herramientas dinámica ... causó que se recalculara angular cada vez como un nuevo valor (aunque era el mismo). Creé una función para almacenar en caché el valor calculado así:
$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;
}
};
Luego en el html, accedí así:
<input type="text" ng-model="$ctrl.myObj.C" uib-tooltip-html="$ctrl.myObj.getTooltip().trusted">
Por lo general, eso sucede cuando devuelves un objeto diferente cada vez.
Por ejemplo, si usa esto en una ng-repeat
:
$scope.getObj = function () {
return [{a: 1}, {b: 2}];
};
Obtendrá este mensaje de error porque Angular intenta tener la "estabilidad" y ejecutará la función hasta que devuelva el mismo resultado 2 veces (en comparación con ===
), que en nuestro caso nunca volverá a ser verdadero porque la función siempre devuelve un nuevo objeto.
console.log({} === {}); // false. Those are two different objects!
En este caso, puede solucionarlo almacenando el objeto en el alcance directamente, por ejemplo
$scope.objData = [{a: 1}, {b: 2}];
$scope.getObj = function () {
return $scope.objData;
};
¡De esa forma siempre regresas el mismo objeto!
console.log($scope.objData === $scope.objData); // true (a bit obvious...)
(Nunca se debe encontrar eso, incluso en aplicaciones complejas).
Actualización: Angular ha agregado una explicación más detallada en su sitio web .
Por loco que parezca, arreglé este error simplemente reiniciando mi navegador cuando simplemente apareció de repente.
Entonces, una solución es borrar el caché de su navegador o reiniciar el navegador.
Solo quería lanzar esta solución aquí, espero que ayude a otros. Estaba obteniendo este problema de iteración porque estaba iterando sobre una propiedad generada que creaba un nuevo objeto cada vez que se llamaba.
Lo arreglé guardando en caché el objeto generado la primera vez que se lo solicitó, y siempre devolviendo el caché, si es que existía. También se agregó un método dirty (), que destruiría los resultados almacenados en caché según sea necesario.
Tenía algo como esto:
function MyObj() {
var myObj = this;
Object.defineProperty(myObj, "computedProperty" {
get: function () {
var retObj = {};
return retObj;
}
});
}
Y aquí está la solución implementada:
function MyObj() {
var myObj = this,
_cached;
Object.defineProperty(myObj, "computedProperty" {
get: function () {
if ( !_cached ) {
_cached = {};
}
return _cached;
}
});
myObj.dirty = function () {
_cached = null;
}
}
También existe la posibilidad de que no sea un ciclo infinito en absoluto. 10 iteraciones no es un número suficientemente grande para concluir que con cualquier cantidad de certeza. Entonces, antes de ir a la caza de locos, es aconsejable descartar esa posibilidad primero.
El método más sencillo para hacerlo es aumentar el recuento de module.config
digestión máximo a un número mucho mayor, lo que se puede hacer en el método module.config
, utilizando el método $rootScopeProvider.digestTtl(limit)
. Si el error infdig
ya no aparece, simplemente tiene una lógica de actualización suficientemente compleja.
Si construye datos o vistas confiando en relojes recursivos, es posible que desee buscar soluciones iterativas (es decir, no confiar en que se inicien nuevos bucles de resumen) usando while
, for
o Array.forEach
. A veces, la estructura está muy anidada y no es recursiva, probablemente no haya mucho que hacer en esos casos, excepto elevar el límite.
Otro método para eliminar errores es mirar los datos del resumen. Si imprimes bastante el JSON, obtienes una matriz de matrices. Cada entrada de nivel superior representa una iteración, cada iteración consiste en una lista de entradas de observación.
Si, por ejemplo, tiene una propiedad que se modifica en $watch
en sí misma, es fácil ver que el valor está cambiando infinitamente:
$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
}
]
]
Por supuesto, en proyectos más grandes esto puede no ser tan simple, especialmente porque el campo msg
menudo tiene el valor "fn: regularInterceptedExpression"
si el reloj es una {{ }}
interpolación.
Aparte de eso, los métodos ya mencionados, como cortar el HTML para encontrar el origen del problema, son por supuesto útiles.
También me gustaría mencionar que recibí este mensaje de error cuando tuve un error tipográfico en la plantillaUrl de una directiva personalizada que tenía en mi proyecto. Debido al error tipográfico, la plantilla no pudo cargarse.
/* @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''
};
Mire en la pestaña de red de las herramientas de desarrollo de su navegador web, y mire si algún recurso tiene un error 404.
Fácil de pasar por alto, porque el mensaje de error es muy críptico y aparentemente no relacionado con el problema real.
Tuve el mismo problema: estaba creando una nueva fecha cada vez. Entonces, para cualquiera que tenga fechas, convertí todas las llamadas como esta:
var date = new Date(); // typeof returns object
a:
var date = new Date().getTime(); // typeof returns number
Inicializar un número en lugar de un objeto de fecha lo resolvió por mí.
Tuve este problema porque estaba haciendo esto
var variableExpense = this.lodash.find(product.variableExpenseList, (ve) => {
return ve.rawMaterial.id = rawMaterial.id;
});
En lugar de esto: (aviso = vs ===), mi prueba de unidad comenzó a fallar y encontré mi estupidez
var variableExpense = this.lodash.find(product.variableExpenseList, (ve) => {
return ve.rawMaterial.id === rawMaterial.id;
});
la manera fácil es: use angular.js, no el archivo min. ábrelo y encuentra la línea:
if ((dirty || asyncQueue.length) && !(ttl--)) {
agregue la línea a continuación:
console.log("aaaa",watch)
y luego actualice su página, en la consola de herramientas de desarrollo, encontrará su código de error.
como Ven dijo, usted está devolviendo objetos diferentes (no idénticos) en cada $digest
ciclo de $digest
, o está alterando los datos demasiadas veces.
La solución más rápida para descubrir qué parte de su aplicación está causando este comportamiento es:
- eliminar todo el HTML sospechoso: básicamente, elimine todo el html de la plantilla y compruebe si no hay advertencias
- si no hay advertencias, agregue pequeñas partes del html que eliminó y verifique si el problema está de vuelta.
- repita el paso 2 hasta que reciba una advertencia: sabrá qué parte de su html es responsable del problema
- Investigue más a fondo: la parte del paso 3 es responsable de mutar los objetos en el
$scope
o devolver objetos no idénticos en cada$digest
ciclo de$digest
. - si aún tiene advertencias de repetición
$digest
después del paso 1, entonces probablemente esté haciendo algo muy sospechoso. Repita los mismos pasos para la plantilla / alcance / controlador principal
También quiere asegurarse de que no está alterando la entrada de sus filtros personalizados
Tenga en cuenta que en JavaScript hay tipos específicos de objetos que no se comportan como lo haría normalmente:
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