Memahami ekspresi ngRepeat 'track by'

101

Saya mengalami kesulitan memahami cara kerja trek dengan ekspresi ng-repeat in angularjs. Dokumentasi sangat langka: http://docs.angularjs.org/api/ng/directive/ngRepeat

Bisakah Anda menjelaskan apa perbedaan antara kedua potongan kode tersebut dalam hal pengikatan data dan aspek relevan lainnya?

dengan: track by $index

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

tanpa (keluaran yang sama)

<!--names is an array-->
<div ng-repeat="(key, value) in names">
   <input ng-model="value[key]">                         
</div>
Jonathan Grupp
sumber
Pertanyaan yang bagus, dengan jawaban yang sangat bagus! Sayangnya OP tidak menerima jawaban - atau menurut Anda pertanyaan itu tidak dijawab dengan benar?
Mawg mengatakan memulihkan Monica
Kamu benar! Saya baru saja menerima jawaban TJ.
Jonathan Grupp

Jawaban:

96

Anda bisa track by $indexjika sumber data Anda memiliki pengenal duplikat

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

Anda tidak dapat mengulang koleksi ini saat menggunakan 'id' sebagai pengenal (duplikat id: 1).

TIDAK BEKERJA:

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

tetapi Anda bisa, jika menggunakan track by $index:

<element ng-repeat="item in dataSource track by $index">
  // something with item ...
</element>
nilsK
sumber
1
Terima kasih atas jawaban anda! Tapi tentunya pengenal duplikat bukan satu-satunya kasus penggunaan. Juga saya ingin tahu apa yang terjadi 'di bawah tenda'.
Jonathan Grupp
2
yah, itu mudah: lihat saja kodenya , semuanya open source;)
nilsK
4
Pertanyaan ini sudah lama tetapi saya masih berpikir ini mungkin membantu memahami lebih baik bennadel.com/blog/… versi singkat penjelasannya di sini docs.angularjs.org/error/ngRepeat/dupes
Annapoorni D
3
Satu hal lagi yang perlu diperhatikan adalah jika Anda dapat menggunakan track by key, Anda akan mendapatkan performa yang lebih baik (blog.500tech.com/is-reactjs-fast). Fitur ini memungkinkan Anda untuk mengaitkan objek JavaScript dengan simpul DOM ngRepeat (Model Objek Dokumen) menggunakan pengenal unik. Dengan adanya pengaitan ini, AngularJS tidak akan $ menghancurkan dan membuat ulang simpul DOM jika tidak perlu. Hal ini dapat memberikan keuntungan kinerja dan pengalaman pengguna yang sangat besar ( bennadel.com/blog/… ).
Braulio
Saya memiliki daftar 700 item aneh. Waktu rendering berubah dari 4 detik menjadi 100ms. Track by harus digunakan untuk semua ngRepeat berdasarkan data yang bersumber dari istirahat.
Patrick
60

ringkasan singkat:

track by digunakan untuk menautkan data Anda dengan pembuatan DOM (dan terutama pembuatan ulang) yang dilakukan dengan ng-repeat.

ketika Anda menambahkan, track bypada dasarnya Anda memberi tahu angular untuk menghasilkan satu elemen DOM per objek data dalam koleksi yang diberikan

ini bisa berguna saat paging dan pemfilteran, atau kasus apa pun di mana objek ditambahkan atau dihapus dari ng-repeatdaftar.

biasanya, tanpa track bysudut akan menautkan objek DOM dengan koleksi dengan memasukkan properti expando - $$hashKey- ke dalam objek JavaScript Anda, dan akan membuatnya kembali (dan mengaitkan kembali objek DOM) dengan setiap perubahan.

penjelasan lengkap:

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

panduan yang lebih praktis:

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

(trek oleh tersedia dalam sudut> 1.2)

Nuriel
sumber
8

Jika Anda bekerja dengan objek yang dilacak oleh pengenal (mis. $ Index) daripada seluruh objek dan Anda memuat ulang data Anda nanti, ngRepeat tidak akan membangun kembali elemen DOM untuk item yang telah dirender , meskipun objek JavaScript dalam koleksi memiliki telah diganti dengan yang baru.

ram1993
sumber
ada referensi yang membuktikan hal ini?
azerafati
apakah ada cara untuk memaksa rendering ulang? atau pekerjaan lain? Saya belum menemukan ini disebutkan di mana pun tetapi saya percaya inilah yang membuat kekacauan bagi saya dan saya sudah membuang banyak waktu.
NeverGiveUp161
1
jangan gunakan lacak oleh atau ubah pengenal unik pada objek yang berubah. Perhatikan Anda tidak dapat mengubah $ indeks, disarankan untuk tidak menggunakan $ indeks sebagai gantinya gunakan pengenal unik untuk objek (mis. Id)
ram1993