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 $digestfür $rootScope. $digestfü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 $digestwird, 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 dirtyauf gesetzt true. Wenn alle Bereiche verarbeitet werden, dirty == true $digestbeginnt eine weitere Tiefenüberquerung ab $rootScope. $digestendet, 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.getAufruf werden Objekte aus der Sammlung (Rückgabewert von getEntities) mit zusätzlichen Informationen im Cache ( HashQueueMapvon hashKey) gespeichert . Bei jedem watch.getAufruf wird ngRepeatversucht, das Objekt anhand seines hashKeyCaches abzurufen. Wenn es nicht im Cache vorhanden ist , ngRepeatspeichert sie im Cache, schafft neue Möglichkeiten, Objekt stellt auf der es schafft DOM - Element, etc .
Nun zu ungefähr hashKey. Normalerweise hashKeywird eine eindeutige Nummer von generiert nextUid(). Aber es kann Funktion sein . hashKeywird 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 hashKeyund existiert nicht im ngRepeatCache. So erzeugt ngRepeatjeder watch.getneue Spielraum dafür mit neuer Uhr für {{entity.id}}. Diese Uhr auf den ersten watch.gethat watch.last == initWatchVal. Also watch.get() != watch.last. So $digestbeginnt neue Traverse. So ngRepeatentsteht 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
hashKeyMethode 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.