angularjs - array - Cómo pasar por los elementos devueltos por una función con ng-repeat?
ng-repeat select (4)
Basado en @przno comment
<body ng-app>
<div ng-repeat="item in t = angular.equals(t, getEntities()) ? t : getEntities()">
Hello {{item.id}}!
</div>
</body>
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
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/
<body ng-app>
<div ng-repeat="entity in getEntities()">
Hello {{entity.id}}!
</div>
</body>
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 alcance 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.
Inicializar la matriz fuera de la repetición
<body ng-app>
<div ng-init="entities = getEntities()">
<div ng-repeat="entity in entities">
Hello {{entity.id}}!
</div>
</div>
</body>
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 alcance . Todos los ámbitos tienen una lista de relojes. Cada reloj tiene el último valor (inicialmente initWatchVal
). Para cada alcance 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 function . 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 alcance 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 alcance con un nuevo reloj. Entonces ... después de 10 travesías, obtienes un error.
Cómo puedes arreglarlo
- No cree objetos nuevos en cada llamada
getEntities()
. - 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.