w3schools example ciclo angularjs angular-digest

example - ciclo digest angularjs



Infinite Digest Loop en el filtro AngularJS (3)

He escrito este filtro personalizado para AngularJS, pero cuando se ejecuta, obtengo el error de bucle de compilación infinito. ¿Por qué ocurre esto y cómo puedo corregirlo?

angular.module("app", []). filter(''department'', function(filterFilter) { return function(items, args) { var productMatches; var output = []; var count = 0; if (args.selectedDepartment.Id !== undefined && args.option) { for (let i = 0; i < items.length; i++) { productMatches = items[i].products.filter(function(el) { return el.Order__r.Department__r.Id === args.selectedDepartment.Id; }); if (productMatches.length !== 0) { output[count] = {}; output[count].products = productMatches; output[count].firstProduct = items[i].firstProduct; count++; } } } return output; }; }).

Este es el HTML relevante:

<tr class=''destination'' ng-repeat-start=''pickupAccount in pickupAccounts | department : {"selectedDepartment": selectedDepartment, "option": displayExclusive }''> <!-- td here --> </tr>

displayExclusive es booleano.


He escrito este filtro personalizado para AngularJS, pero cuando se ejecuta, obtengo el error de bucle de compilación infinito.

Tenga en cuenta que el filtro debe devolver una matriz de la misma estructura de objeto. Cuando activamos el filtro, se activa el ciclo de resumen que se ejecutará sobre nuestro filtro de nuevo. Si algo cambió en la lista de salida, se inicia un nuevo ciclo de resumen y así sucesivamente. después de 10 intentos, nos lanzará la excepción Infinite Digest Loop

Pruebas

Este filtro vacío funcionará (100%). En realidad, aquí no hacemos nada más que devolver el mismo objeto que recibe el filtro.

filter(''department'', function(filterFilter) { return function(items, args) { var output = items; return output; }; })

Ahora la idea principal es: escribir alguna condición para empujar a output objetos de output de la lista de entrada ae los items basados ​​en alguna sentencia if , ae

var output = []; if (args.selectedDepartment.Id !== undefined && args.option) { angular.forEach(items, function(item) { if(<SOME CONDITION>) { output.push(item); } }); }

De esta manera funcionará también.

nuestro caso:

tenemos esta lógica

productMatches = items[i].products.filter(function(el) { return el.Order__r.Department__r.Id === args.selectedDepartment.Id; }); if (productMatches.length !== 0) { output[count] = {}; output[count].products = productMatches; output[count].firstProduct = items[i].firstProduct; count++; }

Aquí modificamos completamente el objeto que se ha almacenado en la output . Así que el próximo ciclo de digestión de nuestros items cambiará una y otra vez.

Conclusión

El propósito principal del filter es filtrar la lista y no modificar el contenido del objeto de la lista.

La lógica mencionada anteriormente que usted escribió está relacionada con la manipulación de datos y no con el filtro. El filtro de department devuelve la misma longitud de elementos.

Para lograr su objetivo, puede usar el mapa lodash o el mapa de guiones bajos, por ejemplo.


output[count] = {};

Por encima de la línea es el principal problema. Crea una nueva instancia, y ng-repeat detectará que el modelo cambia constantemente de forma indefinida. (mientras que piensas que nada ha cambiado desde la perspectiva de la interfaz de usuario)

Para evitar el problema, básicamente debe asegurarse de que cada elemento del modelo siga siendo el mismo, es decir,

firstCallOutput[0] == secondCallOutput[0] && firstCallOutput[1] == secondCallOutput[1] && firstCallOutput[2] == secondCallOutput[2] ...

Esta igualdad debe mantenerse siempre que no cambie el modelo, por lo tanto, ng-repeat no pensará "erróneamente" que el modelo ha sido cambiado.

Tenga en cuenta que dos instancias nuevas no son iguales, es decir, {} != {}


Esto sucede cuando manipula la matriz devuelta de una manera que no coincide con la matriz original. Ver por ejemplo:

.filter("department", function() { return function(items, args) { var output = []; for (var i = 0; i < items.length; i++) { output[i] = {}; output[i] = items[i]; // if you don''t do this, the next filter will fail output[i].product = items[i]; } return output; } }

Puede verlo en el siguiente jsfiddle simplificado: https://jsfiddle.net/u873kevp/1/

Si la matriz devuelta tiene la misma ''estructura'' que la matriz de entrada, causará estos errores.

Debería funcionar en su caso simplemente asignando el artículo original al artículo devuelto:

if (productMatches.length !== 0) { output[count] = items[i]; // do this output[count].products = productMatches; output[count].firstProduct = items[i].firstProduct; count++; }