Comprensione dell'espressione 'track by' ngRepeat


101

Ho difficoltà a capire come funziona la traccia per espressione di ng-repeat in angularjs. La documentazione è molto scarsa: http://docs.angularjs.org/api/ng/directive/ngRepeat

Puoi spiegare qual è la differenza tra questi due frammenti di codice in termini di associazione dati e altri aspetti rilevanti?

con: track by $index

<!--names is an array-->
<div ng-repeat="(key, value) in names track by $index">
  <input ng-model="value[key]">                         
</div>

senza (stessa uscita)

<!--names is an array-->
<div ng-repeat="(key, value) in names">
   <input ng-model="value[key]">                         
</div>

Una bella domanda, con ottime risposte! Peccato che l'OP non abbia accettato una risposta o non credi che alla domanda sia stata data una risposta corretta?
Mawg dice di reintegrare Monica il

Hai ragione! Ho appena accettato la risposta di TJ.
Jonathan Grupp

Risposte:


96

Puoi farlo track by $indexse la tua origine dati ha identificatori duplicati

per esempio: $scope.dataSource: [{id:1,name:'one'}, {id:1,name:'one too'}, {id:2,name:'two'}]

Non puoi iterare questa raccolta mentre utilizzi "id" come identificatore (id duplicato: 1).

NON FUNZIONA:

<element ng-repeat="item.id as item.name for item in dataSource">
  // something with item ...
</element>

ma puoi, se usi track by $index:

<element ng-repeat="item in dataSource track by $index">
  // something with item ...
</element>

1
grazie per la tua risposta! Ma sicuramente gli identificatori duplicati non sono l'unico caso d'uso. Inoltre vorrei sapere cosa sta succedendo "sotto il cofano".
Jonathan Grupp

2
beh, è ​​facile: dai un'occhiata al codice , è tutto open source;)
nilsK

4
Questa domanda è vecchia ma penso ancora che potrebbe aiutare a capire molto meglio bennadel.com/blog/… versione breve della spiegazione qui docs.angularjs.org/error/ngRepeat/dupes
Annapoorni D

3
Un'altra cosa da tenere in considerazione è che se puoi usare traccia per chiave, otterrai prestazioni migliori (blog.500tech.com/is-reactjs-fast). Questa funzione consente di associare un oggetto JavaScript a un nodo ngRepeat DOM (Document Object Model) utilizzando un identificatore univoco. Con questa associazione in atto, AngularJS non $ distruggerà e ricrea i nodi DOM inutilmente. Questo può avere un enorme vantaggio in termini di prestazioni e esperienza utente ( bennadel.com/blog/… ).
Braulio

Ho un elenco di 700 articoli dispari. Il tempo di rendering è passato da 4 secondi a 100 ms. Track by dovrebbe essere utilizzato per tutti gli ngRepeat in base ai dati provenienti da rest.
Patrick

60

un breve riassunto:

track by viene utilizzato per collegare i tuoi dati con la generazione DOM (e principalmente la rigenerazione) realizzata da ng-repeat.

quando aggiungi track by, in pratica, dici ad angular di generare un singolo elemento DOM per oggetto dati nella raccolta data

questo potrebbe essere utile quando si impagina e si filtra, o in qualsiasi caso in cui gli oggetti vengono aggiunti o rimossi ng-repeatdall'elenco.

di solito, senza track byangolare collegherà gli oggetti DOM con la raccolta iniettando una proprietà expando - $$hashKey- nei tuoi oggetti JavaScript e lo rigenererà (e riassocierà un oggetto DOM) ad ogni modifica.

spiegazione completa:

http://www.bennadel.com/blog/2556-using-track-by-with-ngrepeat-in-angularjs-1-2.htm

una guida più pratica:

http://www.codelord.net/2014/04/15/improving-ng-repeat-performance-with-track-by/

(track by è disponibile in angolare> 1.2)


8

Se stai lavorando con gli oggetti tracciati dall'identificatore (ad es. $ Index) invece dell'intero oggetto e ricarichi i tuoi dati in un secondo momento, ngRepeat non ricostruirà gli elementi DOM per gli elementi che ha già reso , anche se gli oggetti JavaScript nella raccolta hanno stato sostituito con nuovi.


qualsiasi riferimento che lo provi?
azerafati

c'è un modo per forzare il rendering? o qualsiasi altro lavoro in giro? Non l'ho trovato menzionato da nessuna parte, ma credo che questo sia ciò che mi crea confusione e ho già perso un sacco di tempo.
NeverGiveUp161

1
o non utilizzare track by o modificare l'identificatore univoco quando si cambia oggetto. Nota che non puoi modificare $ index, si consiglia di non utilizzare $ index invece di utilizzare l'identificatore univoco per l'oggetto (ad es. Id)
ram1993
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.