Kurze Antwort : Benötigen Sie wirklich eine solche Funktion oder können Sie Eigentum verwenden? http://jsfiddle.net/awnqm/1/
Lange Antwort
Der Einfachheit halber beschreibe ich nur Ihren Fall - ngRepeat für ein Array von Objekten. Außerdem werde ich einige Details weglassen.
AngularJS verwendet Dirty Checking, um Änderungen zu erkennen. Wenn die Anwendung gestartet wird, läuft sie $digest
für $rootScope
. $digest
führt die Tiefenüberquerung für die Hierarchie des Bereichs durch . Alle Zielfernrohre haben eine Liste von Uhren. Jede Uhr hat (anfangs initWatchVal
) den letzten Wert . Für jeden Bereich, der für alle Uhren ausgeführt $digest
wird, wird der aktuelle Wert ( watch.get(scope)
) abgerufen und mit verglichen watch.last
. Wenn der aktuelle Wert nicht gleich ist watch.last
(immer für den ersten Vergleich) $digest
, wird dirty
auf gesetzt true
. Wenn alle Bereiche verarbeitet werden, dirty == true
$digest
beginnt eine weitere Tiefenüberquerung ab $rootScope
. $digest
endet, wenn Dirty == false oder Anzahl der Durchläufe == 10. Im letzteren Fall wurde der Fehler "10 $ Digest () - Iterationen erreicht" angezeigt. wird protokolliert.
Nun zu ungefähr ngRepeat
. Bei jedem watch.get
Aufruf werden Objekte aus der Sammlung (Rückgabewert von getEntities
) mit zusätzlichen Informationen im Cache ( HashQueueMap
von hashKey
) gespeichert . Bei jedem watch.get
Aufruf wird ngRepeat
versucht, das Objekt anhand seines hashKey
Caches abzurufen. Wenn es nicht im Cache vorhanden ist , ngRepeat
speichert sie im Cache, schafft neue Möglichkeiten, Objekt stellt auf der es schafft DOM - Element, etc .
Nun zu ungefähr hashKey
. Normalerweise hashKey
wird eine eindeutige Nummer von generiert nextUid()
. Aber es kann Funktion sein . hashKey
wird nach dem Generieren im Objekt für die zukünftige Verwendung gespeichert.
Warum Ihr Beispiel einen Fehler generiert : Die Funktion gibt getEntities()
immer ein Array mit einem neuen Objekt zurück. Dieses Objekt hat hashKey
und existiert nicht im ngRepeat
Cache. So erzeugt ngRepeat
jeder watch.get
neue Spielraum dafür mit neuer Uhr für {{entity.id}}
. Diese Uhr auf den ersten watch.get
hat watch.last == initWatchVal
. Also watch.get() != watch.last
. So $digest
beginnt neue Traverse. So ngRepeat
entsteht mit neuer Uhr ein neuer Spielraum. Also ... nach 10 Durchläufen erhalten Sie einen Fehler.
Wie Sie es beheben können
- Erstellen Sie nicht bei jedem
getEntities()
Aufruf neue Objekte .
- Wenn Sie neue Objekte erstellen müssen, können Sie eine
hashKey
Methode für diese hinzufügen . Beispiele finden Sie in diesem Thema .
Hoffe, dass Leute, die AngularJS-Interna kennen, mich korrigieren, wenn ich in etwas falsch liege.
Do not create new objects on every getEntities() call.
ziemlich einfach wie<div ng-repeat="entity in entities = (entities || getEntities())">
getEntities()
immer das gleiche Array zurückgegeben wird. Wenn sich das Array jemals ändert, erhalten Sie es nicht imng-repeat
Initialisieren Sie das Array außerhalb der Wiederholung
quelle
getEntities()
im Lebenszyklus des Programms etwas anderes zurückgegeben wird. Sagen wir zum Beispiel, dassgetEntities()
ein$http.get
. Wenn die endgültige Auflösung (Sie haben den AJAX-Aufruf durchgeführt)entities
bereits initialisiert ist.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.
Dies wurde hier gemeldet und erhielt diese Antwort:
Sie können sehen, dass dieses Verhalten verschwindet, wenn Sie das Array außerhalb des Hauptcontrollers verschieben:
denn jetzt gibt es jedes Mal das gleiche Objekt zurück. Möglicherweise müssen Sie Ihr Modell neu erstellen, um eine Eigenschaft für den Bereich anstelle einer Funktion zu verwenden:
quelle
Basierend auf @przno Kommentar
Übrigens: Die zweite Lösung @Artem Andreev schlägt vor, dass Angular 1.1.4 und höher nicht funktioniert, während die erste das Problem nicht löst. Ich fürchte, dies ist die weniger stachelige Lösung ohne Nachteile in der Funktionalität
quelle
Item.id
ist was es sollte b. Vielen Dank