Respuesta corta : ¿realmente necesita esa función o puede usar la propiedad? http://jsfiddle.net/awnqm/1/
Respuesta larga
Por simplicidad, describiré solo su caso: ngRepeat para una matriz de objetos. Además, omitiré algunos detalles.
AngularJS usa verificación sucia para detectar cambios. Cuando se inicia la aplicación que se ejecuta $digestpara $rootScope. $digesthará un recorrido en profundidad primero para la jerarquía del alcance . Todos los alcances tienen lista de relojes. Cada reloj tiene el último valor (inicialmente initWatchVal). Para cada alcance de todos los relojes, lo $digestejecuta, obtiene el valor actual ( watch.get(scope)) y lo compara con watch.last. Si el valor actual no es igual a watch.last(siempre para la primera comparación) se $digestestablece dirtyen true. Cuando se procesan todos los ámbitos, dirty == true $digestcomienza otro recorrido en profundidad desde $rootScope. $digesttermina cuando está sucio == falso o número de recorridos == 10. En el último caso, el error "10 $ digest () iteraciones alcanzadas". se registrará.
Ahora sobre ngRepeat. Para cada watch.getllamada, almacena objetos de la colección (valor de retorno de getEntities) con información adicional en caché ( HashQueueMappor hashKey). Para cada watch.getllamada, ngRepeatintenta obtener un objeto por su hashKeycaché. Si no existe en la memoria caché, ngRepeatlo almacena en la memoria caché, crea nuevas posibilidades, pone objeto en ella, crea elemento DOM, etc .
Ahora sobre hashKey. Generalmente hashKeyes un número único generado por nextUid(). Pero puede ser funcional . hashKeyse almacena en el objeto después de generarlo para uso futuro.
Por qué su ejemplo genera error : la función getEntities()siempre devuelve una matriz con un nuevo objeto. Este objeto no tiene hashKeyni existe en la ngRepeatcaché. Entonces ngRepeaten cada uno watch.getgenera un nuevo alcance para él con un nuevo reloj {{entity.id}}. Este primer reloj watch.gettiene watch.last == initWatchVal. Entonces watch.get() != watch.last. Entonces $digestcomienza una nueva travesía. Entonces ngRepeatcrea un nuevo alcance con un nuevo reloj. Entonces ... después de 10 recorridos obtienes un error.
¿Cómo puedes arreglarlo?
- No cree nuevos objetos en cada
getEntities()llamada.
- Si necesita crear nuevos objetos, puede agregar un
hashKeymétodo para ellos. Consulte este tema para ver ejemplos.
Espero que las personas que conocen los componentes internos de AngularJS me corrijan si me equivoco en algo.
Do not create new objects on every getEntities() call.se puede arreglar bastante fácilmente así:<div ng-repeat="entity in entities = (entities || getEntities())">getEntities()siempre devuelva la misma matriz, si la matriz alguna vez cambia, no la obtendrá en elng-repeatInicializar la matriz fuera de la repetición
fuente
getEntities()devuelve algo diferente en el ciclo de vida del programa. Digamos, por ejemplo, quegetEntities()desencadena un$http.get. Cuando el get finalmente se resuelva (realizó la llamada AJAX),entitiesya estará inicializado.The only appropriate use of ngInit is for aliasing special properties of ngRepeat. Besides this case, you should use controllers rather than ngInit to initialize values on a scope.Esto se informó aquí y obtuvo esta respuesta:
Puede ver que este comportamiento desaparece si mueve la matriz fuera del controlador principal:
porque ahora devuelve el mismo objeto cada vez. Es posible que deba rediseñar su modelo para usar una propiedad en el alcance en lugar de una función:
fuente
Basado en el comentario de @przno
Por cierto, la segunda solución @Artem Andreev sugiere que no funciona en Angular 1.1.4 y superior, mientras que la primera no resuelve el problema. Entonces, me temo que por ahora esta es la solución menos puntiaguda sin desventajas en la funcionalidad
fuente
Item.ides lo que debería b. Gracias