Saya memiliki arahan dengan isolate-scope (sehingga saya dapat menggunakan kembali arahan di tempat lain), dan ketika saya menggunakan arahan ini dengan ng-repeat
, itu gagal berfungsi.
Saya telah membaca semua dokumentasi dan jawaban Stack Overflow tentang topik ini dan memahami masalahnya. Saya yakin saya telah menghindari semua tipu muslihat biasa.
Jadi saya mengerti bahwa kode saya gagal karena cakupan yang dibuat oleh ng-repeat
direktif. Direktif saya sendiri membuat lingkup-isolasi dan melakukan pengikatan data dua arah ke objek dalam lingkup induk. Direktif saya akan menetapkan nilai objek baru ke variabel terikat ini dan ini berfungsi dengan sempurna ketika direktif saya digunakan tanpa ng-repeat
(variabel induk diperbarui dengan benar). Namun, dengan ng-repeat
, tugas membuat variabel baru dalam ng-repeat
cakupan dan variabel induk tidak melihat perubahannya. Semua ini seperti yang diharapkan berdasarkan apa yang telah saya baca.
Saya juga membaca bahwa ketika ada beberapa arahan pada elemen tertentu, hanya satu ruang lingkup yang dibuat. Dan bahwa a priority
dapat disetel di setiap arahan untuk menentukan urutan penerapan arahan; direktif diurutkan berdasarkan prioritas dan kemudian fungsi kompilasinya dipanggil (cari kata prioritas di http://docs.angularjs.org/guide/directive ).
Jadi saya berharap saya dapat menggunakan prioritas untuk memastikan bahwa arahan saya berjalan terlebih dahulu dan akhirnya membuat lingkup-isolasi, dan ketika ng-repeat
dijalankan, itu menggunakan kembali lingkup-isolasi daripada membuat lingkup yang secara prototipikal mewarisi dari lingkup induk. The ng-repeat
negara dokumentasi yang yang berjalan direktif pada tingkat prioritas 1000
. Tidak jelas apakah 1
itu tingkat prioritas yang lebih tinggi atau tingkat prioritas yang lebih rendah. Ketika saya menggunakan tingkat prioritas 1
dalam arahan saya, tidak ada bedanya, jadi saya mencoba 2000
. Tapi itu memperburuk keadaan: ikatan dua arah undefined
saya menjadi dan arahan saya tidak menampilkan apa pun.
Saya telah membuat biola untuk menunjukkan masalah saya . Saya telah mengomentari priority
pengaturan dalam arahan saya. Saya memiliki daftar objek nama dan direktif disebut name-row
yang menunjukkan bidang nama depan dan belakang di objek nama. Ketika nama yang ditampilkan diklik, saya ingin mengatur selected
variabel dalam lingkup utama. Larik nama, selected
variabel diteruskan ke name-row
direktif menggunakan data-binding dua arah.
Saya tahu bagaimana membuat ini bekerja dengan memanggil fungsi di lingkup utama. Saya juga tahu bahwa jika selected
ada di dalam objek lain, dan saya mengikat objek luar, semuanya akan bekerja. Tetapi saya tidak tertarik dengan solusi tersebut saat ini.
Sebaliknya, pertanyaan yang saya miliki adalah:
- Bagaimana cara mencegah
ng-repeat
pembuatan cakupan yang secara prototipikal mewarisi dari lingkup induk, dan malah membuatnya menggunakan lingkup-isolasi direktif saya? - Mengapa tingkat prioritas
2000
dalam arahan saya tidak berfungsi? - Dengan Batarang, apakah mungkin untuk mengetahui jenis scope yang digunakan?
scope: true
untuk direktif Anda. Lihat juga (jika Anda belum melakukannya) stackoverflow.com/questions/14914213/… Juga, hanya karena sebuah direktif akan digunakan di banyak tempat tidak berarti kita harus secara otomatis menggunakan lingkup isolasi.ng-repeat
. Menurut saya, sangat berharga untuk dapat menggabungkan arahan yang berdiri sendiring-repeat
. Untuk dilanjutkan ...ng-repeat
tidak boleh memiliki ruang lingkup.ng-repeat
memiliki ruang lingkup masuk akal untuk kasus penggunaan biasa, jadi saya tidak menyarankan itu diubah. Sebagai gantinya, seperti yang saya komentari dalam jawaban Alex Osborn, saya pikir saya akan membuat arahan berulang berdasarkanng-repeat
yang tidak menciptakan ruang lingkupnya sendiri. Ini kemudian dapat digunakan untuk mengulangi arahan yang memiliki cakupan isolatnya sendiri. Untuk dilanjutkan ...ng-repeat
atau direktif berulang tanpa cakupan kustom. Saya pikir tidak apa-apa bagi "penelepon" untuk mengetahui hal ini, tetapi tidak baik bagi "callee" (perintah yang diulangi) untuk mengetahui apakah itu diulangi atau tidak. Untuk dilanjutkan ...Jawaban:
Oke, melalui banyak komentar di atas, saya menemukan kebingungannya. Pertama, beberapa poin klarifikasi:
Berikut adalah contoh dari kode yang sama tetapi dengan perintah yang dihapus:
Berikut adalah JSFiddle yang menunjukkan bahwa itu tidak akan berhasil. Anda mendapatkan hasil yang sama persis seperti dalam arahan Anda.
Mengapa tidak berhasil? Karena cakupan di AngularJS menggunakan pewarisan prototipe. Nilai
selected
pada lingkup induk Anda adalah primitif . Dalam JavaScript, ini berarti akan ditimpa ketika seorang anak menetapkan nilai yang sama. Ada aturan emas dalam cakupan AngularJS: nilai model harus selalu ada.
di dalamnya. Artinya, mereka tidak boleh primitif. Lihat jawaban SO ini untuk informasi lebih lanjut.Berikut adalah gambaran dari tampilan awal scope.
Setelah mengklik item pertama, cakupannya sekarang akan terlihat seperti ini:
Perhatikan bahwa
selected
properti baru telah dibuat pada cakupan ngRepeat. Cakupan pengontrol 003 tidak diubah.Anda mungkin bisa menebak apa yang terjadi saat kita mengklik item kedua:
Jadi masalah Anda sebenarnya tidak disebabkan oleh ngRepeat sama sekali - ini disebabkan oleh pelanggaran aturan emas di AngularJS. Cara untuk memperbaikinya adalah dengan menggunakan properti objek:
Ini adalah JSFiddle kedua yang menunjukkan bahwa ini juga berfungsi.
Berikut adalah tampilan cakupan awalnya:
Setelah mengklik item pertama:
Di sini, lingkup pengontrol terpengaruh, seperti yang diinginkan.
Juga, untuk membuktikan bahwa ini masih akan bekerja dengan direktif Anda dengan lingkup terisolasi (karena, sekali lagi, ini tidak ada hubungannya dengan masalah Anda), berikut adalah JSFiddle untuk itu juga, tampilan harus mencerminkan objek. Anda akan mencatat bahwa satu-satunya perubahan yang diperlukan adalah menggunakan objek, bukan primitif .
Cakupan awalnya:
Cakupan setelah mengklik item pertama:
Sebagai kesimpulan: sekali lagi, masalah Anda bukan pada lingkup isolate dan bukan pada cara kerja ngRepeat. Masalah Anda adalah bahwa Anda melanggar aturan yang diketahui menyebabkan masalah ini. Model di AngularJS harus selalu memiliki
.
.sumber
.
aturan emas hanya diperlukan untuk cakupan yang memiliki warisan prototipe. Dengan isolate-scopes, variabel yang Anda minati didefinisikan dalamscope: {}
definisi di direktif, dan oleh karena itu variabel tersebut akan ada di lingkup isolate dari awal. Juga, mereka tidak menutupi variabel induk karena lingkup-isolate tidak secara prototipikal mewarisi dari lingkup induk. yaitu tidak ada ruang lingkup "induk" untuk ditutup..
.Tanpa secara langsung mencoba menghindari menjawab pertanyaan Anda, sebagai gantinya lihatlah biola berikut:
http://jsfiddle.net/dVPLM/
Poin kuncinya adalah bahwa alih-alih mencoba melawan dan mengubah perilaku konvensional Angular, Anda dapat menyusun arahan Anda untuk bekerja
ng-repeat
daripada mencoba menimpanya.Di template Anda:
Dalam arahan Anda:
Menanggapi pertanyaan Anda:
ng-repeat
akan membuat ruang lingkup, Anda seharusnya tidak mencoba mengubah ini.sumber
ng-repeat
atau tidak. Mungkin saat pertama kali ditulis, tidak pernah digunakan denganng-repeat
. Dan suatu saat di masa mendatang, ini mungkin digunakan denganng-repeat
, dan pada saat itu, seharusnya berfungsi tanpa penulisan ulang. Semoga rilis AngularJS di masa mendatang akan memungkinkan hal ini.ng-repeat
atau tidak. Tetapi tampaknya saya harus meneruskan fungsi ke direktif sehingga dapat memodifikasi variabel dalam lingkup induk, alih-alih dapat mengubah pengikatan dua arah dalam lingkup direktif itu sendiri. Pengikatan dua arah dan arahan yang dapat digunakan kembali adalah dua hal favorit saya tentang AngularJS danng-repeat
terbukti menjadi lalat dalam salep. Mungkin saya bisa menulisng-repeat
padanan yang tidak membuat ruang lingkupnya sendiri.