Jawaban singkatnya : apakah Anda benar-benar membutuhkan fungsi seperti itu atau Anda dapat menggunakan properti? http://jsfiddle.net/awnqm/1/
Jawaban panjang
Untuk kesederhanaan saya hanya akan menjelaskan kasus Anda - ngRepeat untuk berbagai objek. Juga, saya akan menghilangkan beberapa detail.
AngularJS menggunakan pemeriksaan kotor untuk mendeteksi perubahan. Ketika aplikasi dijalankan berjalan $digest
untuk $rootScope
. $digest
akan melakukan penjelajahan kedalaman pertama untuk hierarki cakupan . Semua cakupan memiliki daftar jam tangan. Setiap jam tangan memiliki nilai terakhir (awalnya initWatchVal
). Untuk setiap cakupan untuk semua jam tangan $digest
menjalankannya, mendapatkan nilai saat ini ( watch.get(scope)
) dan membandingkannya watch.last
. Jika nilai saat ini tidak sama dengan watch.last
(selalu untuk perbandingan pertama) $digest
set dirty
ke true
. Saat semua cakupan diproses jika dirty == true
$digest
memulai traversal kedalaman pertama lainnya dari $rootScope
. $digest
berakhir ketika dirty == false atau jumlah traversals == 10. Dalam kasus terakhir, error "10 $ digest () iterations tercapai." akan dicatat.
Sekarang tentang ngRepeat
. Untuk setiap watch.get
panggilan itu menyimpan objek dari koleksi (nilai yang dikembalikan getEntities
) dengan informasi tambahan dalam cache ( HashQueueMap
oleh hashKey
). Untuk setiap watch.get
panggilan ngRepeat
mencoba untuk mendapatkan objek hashKey
dari cache-nya. Jika tidak ada di cache, ngRepeat
simpan di cache, membuat cakupan baru, meletakkan objek di atasnya, membuat elemen DOM, dll .
Sekarang tentang hashKey
. Biasanya hashKey
nomor unik dihasilkan oleh nextUid()
. Tapi itu bisa berfungsi . hashKey
disimpan dalam objek setelah dibuat untuk digunakan di masa mendatang.
Mengapa contoh Anda menghasilkan kesalahan : fungsi getEntities()
selalu mengembalikan array dengan objek baru. Objek ini tidak memiliki hashKey
dan tidak ada di ngRepeat
cache. Jadi ngRepeat
pada masing-masing watch.get
menghasilkan ruang lingkup baru untuk itu dengan jam tangan baru {{entity.id}}
. Jam tangan ini pertama kali watch.get
punya watch.last == initWatchVal
. Jadi watch.get() != watch.last
. Jadi mulailah $digest
lintasan baru. Jadi ngRepeat
buat ruang lingkup baru dengan jam tangan baru. Jadi ... setelah 10 traverse Anda mendapatkan error.
Bagaimana Anda bisa memperbaikinya
- Jangan membuat objek baru di setiap
getEntities()
panggilan.
- Jika Anda perlu membuat objek baru, Anda dapat menambahkan
hashKey
metode untuk mereka. Lihat topik ini sebagai contoh.
Semoga orang yang mengetahui internal AngularJS akan mengoreksi saya jika saya salah dalam sesuatu.
Do not create new objects on every getEntities() call.
itu dapat diperbaiki dengan mudah seperti ini:<div ng-repeat="entity in entities = (entities || getEntities())">
getEntities()
selalu mengembalikan array yang sama, jika array pernah berubah, Anda tidak akan mendapatkannya ding-repeat
Inisialisasi larik di luar pengulangan
sumber
getEntities()
mengembalikan sesuatu yang berbeda dalam siklus hidup program. Katakan, misalnya,getEntities()
pemicu itu$http.get
. Ketika get akhirnya menyelesaikan (Anda membuat panggilan AJAX),entities
akan sudah diinisialisasi.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.
Ini dilaporkan di sini dan mendapat tanggapan ini:
Anda dapat melihat perilaku ini hilang jika Anda memindahkan array di luar pengontrol Utama:
karena sekarang mengembalikan objek yang sama setiap saat. Anda mungkin perlu merancang ulang model Anda untuk menggunakan properti pada scope alih-alih fungsi:
sumber
Berdasarkan komentar @przno
Solusi kedua BTW @Artem Andreev menyarankan tidak berfungsi di Angular 1.1.4 dan yang lebih baru, sedangkan solusi pertama tidak menyelesaikan masalah. Jadi, saya khawatir untuk saat ini ini adalah solusi yang kurang tajam tanpa kerugian dalam fungsionalitas
sumber
Item.id
adalah apa yang seharusnya b. Terima kasih