Cómo pasar por los elementos devueltos por una función con ng-repeat?

Quiero crear divs repetidamente, los elementos son objetos devueltos por una función. Sin embargo, los siguientes errores de informe de código: 10 $ digest () iteraciones alcanzadas. Aborto! jsfiddle está aquí: http://jsfiddle.net/BraveOstrich/awnqm/

 
Hello {{entity.id}}!

Respuesta corta : ¿realmente necesita esa función o puede usar propiedad? http://jsfiddle.net/awnqm/1/

Respuesta larga

Por simplicidad, describiré solo su caso – ngRepet para una matriz de objetos. Además, omitiré algunos detalles.

AngularJS usa verificación sucia para detectar cambios. Cuando se inicia la aplicación, ejecuta $digest for $rootScope . $digest hará un recorrido en profundidad para la jerarquía del scope . Todos los ámbitos tienen una lista de relojes. Cada reloj tiene el último valor (inicialmente initWatchVal ). Para cada scope para todos los relojes, $digest ejecuta, 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) $digest set dirty to true . Cuando se procesan todos los ámbitos, si dirty == true $digest inicia otro recorrido en profundidad desde $rootScope . $digest finaliza cuando dirty == false o number of transversales == 10. En este último caso, se produce el error “10 $ digest () iterations.” será registrado.

Ahora sobre ngRepeat . Para cada watch.get call, almacena objetos de la colección (devuelve el valor de getEntities ) con información adicional en caché ( HashQueueMap por hashKey ). Para cada watch.get llame a ngRepeat intente obtener el objeto por su hashKey desde el caché. Si no existe en la memoria caché, ngRepeat almacena en caché, crea un nuevo ámbito, coloca un objeto en ella, crea un elemento DOM, etc.

Ahora sobre hashKey . Por hashKey general, hashKey es el número único generado por nextUid() . Pero puede ser una función . hashKey se almacena en el objeto después de generar para su uso futuro.

Por qué su ejemplo genera un error : la función getEntities() siempre devuelve una matriz con un nuevo objeto. Este objeto no tiene hashKey y no existe en ngRepeat cache. Así que ngRepeat en cada watch.get genera un nuevo scope para él con un nuevo reloj para {{entity.id}} . Este reloj en first watch.get tiene watch.last == initWatchVal . Así que watch.get() != watch.last . Entonces $digest comienza una nueva poligonal. Entonces ngRepeat crea un nuevo scope con un nuevo reloj. Entonces … después de 10 travesías, obtienes un error.

Cómo puedes arreglarlo

  1. No cree objetos nuevos en cada llamada getEntities() .
  2. Si necesita crear nuevos objetos, puede agregar el método hashKey para ellos. Vea este tema para ejemplos.

Espero que las personas que conocen el interior de AngularJS me corrijan si me equivoco en algo.

Inicializar la matriz fuera de la repetición

  
Hello {{entity.id}}!

Esto fue informado aquí y obtuve esta respuesta:

Su getter no es idempotente y cambia el modelo (al generar una nueva matriz cada vez que se llama). Esto obliga a angular a seguir llamándolo con la esperanza de que el modelo finalmente se estabilice, pero nunca lo hace, por lo que angular se da por vencido y arroja una excepción.

Los valores que devuelve el getter son iguales pero no idénticos y ese es el problema.

Puedes ver que este comportamiento desaparece si mueves la matriz fuera del controlador principal:

 var array = [{id:'angularjs'}]; function Main($scope) { $scope.getEntities = function(){return array;}; }; 

porque ahora está devolviendo el mismo objeto cada vez. Es posible que necesite volver a diseñar su modelo para usar una propiedad en el scope en lugar de una función:

Trabajamos a su alrededor asignando el resultado del método del controlador a una propiedad, y haciendo ng: repito contra él.

Basado en @przno comment

  
Hello {{item.id}}!

La segunda solución BTW @Artem Andreev sugiere que no está funcionando en Angular 1.1.4 y posteriores, mientras que la primera no resuelve el problema. Por lo tanto, me temo que por ahora esta es la solución menos puntiaguda sin desventajas en la funcionalidad