Saya mencari beberapa panduan yang dapat digunakan untuk membantu menentukan jenis ruang lingkup yang digunakan saat menulis arahan baru. Idealnya, saya ingin sesuatu yang mirip dengan bagan alur yang menuntun saya melalui banyak pertanyaan dan muncul jawaban yang benar - tidak ada ruang lingkup baru baru, ruang lingkup anak baru, atau ruang lingkup isolat baru - tetapi itu kemungkinan meminta terlalu banyak. Berikut seperangkat pedoman remeh saya saat ini:
- Jangan menggunakan lingkup yang terisolasi jika elemen yang akan menggunakan arahan menggunakan model-ng.
Lihat Dapatkah saya menggunakan model-ng dengan cakupan terisolasi? dan
mengapa formatters tidak berfungsi dengan cakupan terisolasi? - Jika arahan tidak mengubah properti lingkup / model apa pun, jangan buat lingkup baru
- Cakupan isolasi tampaknya berfungsi dengan baik jika arahan merangkum satu set elemen DOM ( dokumentasi mengatakan "struktur DOM kompleks") dan arahan akan digunakan sebagai elemen, atau tanpa arahan lain pada elemen yang sama.
Saya sadar bahwa menggunakan arahan dengan cakupan terisolasi pada elemen memaksa semua arahan lain pada elemen yang sama untuk menggunakan lingkup isolasi yang sama (satu), jadi bukankah ini sangat membatasi ketika ruang lingkup isolat dapat digunakan?
Saya berharap beberapa dari tim Angular-UI (atau yang lain yang telah menulis banyak arahan) dapat berbagi pengalaman mereka.
Tolong jangan tambahkan jawaban yang hanya mengatakan "gunakan cakupan terisolasi untuk komponen yang dapat digunakan kembali".
sumber
scope: true
akan membuat lingkup anak menggunakan$scope.new()
secara otomatis.scope: false
(default, tidak ada ruang lingkup baru),scope: true
(ruang lingkup baru yang mewarisi secara prototipe), danscope: { ... }
(ruang lingkup isolat baru).Jawaban:
Pertanyaan yang sangat bagus! Saya akan senang mendengar apa yang dikatakan orang lain, tapi di sini adalah pedoman saya gunakan.
Premis ketinggian tinggi: ruang lingkup digunakan sebagai "lem" yang kami gunakan untuk berkomunikasi antara pengendali induk, direktif, dan template direktif.
Lingkup Induk:,
scope: false
jadi tidak ada ruang lingkup sama sekaliSaya tidak terlalu sering menggunakan ini, tetapi seperti kata @MarkRajcok, jika direktif tidak mengakses variabel ruang lingkup (dan jelas tidak mengatur apa pun!) Maka ini baik-baik saja sejauh yang saya ketahui. Ini juga bermanfaat untuk arahan anak yang hanya digunakan dalam konteks arahan orang tua (meskipun selalu ada pengecualian untuk ini) dan yang tidak memiliki template. Pada dasarnya apa pun dengan templat tidak termasuk berbagi lingkup, karena Anda secara inheren mengekspos cakupan untuk akses dan manipulasi (tapi saya yakin ada pengecualian untuk aturan ini).
Sebagai contoh, saya baru-baru ini membuat arahan yang menggambar grafik vektor (statis) menggunakan perpustakaan SVG saya sedang dalam proses penulisan. Ini
$observe
dua atribut (width
danheight
) dan menggunakannya dalam perhitungannya, tetapi tidak menetapkan atau membaca variabel lingkup apa pun dan tidak memiliki templat. Ini adalah kasus penggunaan yang baik untuk tidak menciptakan cakupan lain; kita tidak membutuhkannya, jadi mengapa repot-repot?Tetapi dalam arahan SVG yang lain, saya membutuhkan satu set data untuk digunakan dan juga harus menyimpan sedikit keadaan. Dalam hal ini, menggunakan ruang lingkup orang tua tidak bertanggung jawab (sekali lagi, secara umum). Jadi sebagai gantinya ...
Lingkup Anak:
scope: true
Arahan dengan lingkup anak adalah sadar konteks dan dimaksudkan untuk berinteraksi dengan lingkup saat ini.
Jelas, keuntungan utama dari ini di atas lingkup isolasi adalah bahwa pengguna bebas menggunakan interpolasi pada atribut apa pun yang mereka inginkan; mis. menggunakan
class="item-type-{{item.type}}"
direktif dengan cakupan isolat tidak akan berfungsi secara default, tetapi berfungsi baik pada direktif dengan cakupan anak karena apa pun yang diinterpolasi masih dapat ditemukan secara default dalam lingkup induk. Juga, arahan itu sendiri dapat dengan aman mengevaluasi atribut dan ekspresi dalam konteks ruang lingkupnya sendiri tanpa khawatir tentang polusi atau kerusakan pada induknya.Sebagai contoh, tooltip adalah sesuatu yang baru saja ditambahkan; ruang lingkup isolasi tidak akan berfungsi (secara default, lihat di bawah) karena diharapkan kita akan menggunakan arahan lain atau atribut yang diinterpolasi di sini. Tip alat hanyalah tambahan. Tetapi tooltip juga perlu mengatur beberapa hal pada lingkup untuk digunakan dengan sub-direktif dan / atau template dan jelas untuk mengelola keadaannya sendiri, sehingga akan sangat buruk untuk menggunakan lingkup induk. Kami mencemari atau merusaknya, dan bueno juga tidak.
Saya menemukan diri saya menggunakan cakupan anak lebih sering daripada lingkup isolasi atau orangtua.
Ruang lingkup isolasi:
scope: {}
Ini untuk komponen yang dapat digunakan kembali. :-)
Tapi serius, saya menganggap "komponen yang dapat digunakan kembali" sebagai "komponen mandiri". Maksudnya adalah bahwa mereka harus digunakan untuk tujuan tertentu, jadi menggabungkan mereka dengan arahan lain atau menambahkan atribut interpolasi lainnya ke simpul DOM secara inheren tidak masuk akal.
Untuk lebih spesifik, apa pun yang diperlukan untuk fungsi mandiri ini disediakan melalui atribut tertentu yang dievaluasi dalam konteks lingkup induk; mereka bisa berupa string satu arah ('@'), ekspresi satu arah ('&'), atau binding variabel dua arah ('=').
Pada komponen mandiri, tidak masuk akal untuk perlu menerapkan arahan atau atribut lain karena itu ada dengan sendirinya. Gayanya diatur oleh template sendiri (jika perlu) dan dapat memiliki konten yang sesuai ditransklusikan (jika perlu). Itu standalone, jadi kami menempatkannya dalam ruang lingkup terisolasi juga untuk mengatakan: "Jangan main-main dengan ini. Saya memberi Anda API yang didefinisikan melalui beberapa atribut ini."
Praktik terbaik yang baik adalah dengan mengecualikan hal-hal berbasis template dari directive link dan fungsi pengontrol sebanyak mungkin. Ini memberikan titik konfigurasi "seperti API" lainnya: pengguna direktif dapat dengan mudah mengganti templat! Fungsionalitasnya tetap sama, dan API internalnya tidak pernah disentuh, tetapi kami dapat mengacaukan styling dan implementasi DOM sebanyak yang kami butuhkan. ui / bootstrap adalah contoh yang bagus tentang bagaimana melakukan ini dengan baik karena Peter & Pawel mengagumkan.
Cakupan isolasi juga bagus untuk digunakan dengan transklusi. Ambil tab; mereka tidak hanya seluruh fungsionalitas, tetapi apa pun yang ada di dalamnya dapat dievaluasi secara bebas dari dalam lingkup induk sambil meninggalkan tab (dan panel) untuk melakukan apa pun yang mereka inginkan. Tab jelas memiliki sendiri negara , yang termasuk di lingkup (untuk berinteraksi dengan template), tetapi bahwa negara tidak ada hubungannya dengan konteks yang digunakan - itu sepenuhnya internal untuk apa yang membuat tab direktif direktif tab. Lebih jauh, tidak masuk akal untuk menggunakan arahan lain dengan tab. Itu adalah tab - dan kami sudah mendapatkan fungsionalitas itu!
Kelilinginya dengan lebih banyak fungsionalitas atau transklusikan lebih banyak fungsi, tetapi arahan sudah seperti itu.
Semua yang mengatakan, saya harus mencatat bahwa ada cara di sekitar beberapa keterbatasan (yaitu fitur) dari ruang lingkup yang terisolasi, seperti @ProLoser mengisyaratkan dalam jawabannya. Sebagai contoh, di bagian lingkup anak, saya menyebutkan interpolasi pada atribut non-direktif melanggar ketika menggunakan ruang lingkup isolat (secara default). Tetapi pengguna dapat, misalnya, cukup menggunakan
class="item-type-{{$parent.item.type}}"
dan itu sekali lagi akan berfungsi. Jadi, jika ada alasan kuat untuk menggunakan ruang lingkup terisolasi di atas ruang lingkup anak tetapi Anda khawatir tentang beberapa keterbatasan ini, ketahuilah bahwa Anda dapat mengatasi hampir semua dari mereka jika Anda perlu.Ringkasan
Arahan tanpa ruang lingkup baru hanya untuk dibaca; mereka sepenuhnya tepercaya (yaitu internal ke aplikasi) dan mereka tidak menyentuh jack. Arahan dengan cakupan anak menambah fungsionalitas, tetapi itu bukan satu-satunya fungsi. Terakhir, lingkup isolasi adalah untuk arahan yang merupakan tujuan keseluruhan; mereka berdiri sendiri, jadi tidak apa-apa (dan paling "benar") untuk membiarkan mereka nakal.
Saya ingin mengeluarkan pikiran awal saya, tetapi karena saya memikirkan lebih banyak hal, saya akan memperbarui ini. Tapi sial - ini panjang untuk jawaban SO ...
PS: Benar-benar tangensial, tetapi karena kita berbicara tentang ruang lingkup, saya lebih suka mengatakan "prototipikal" sedangkan yang lain lebih suka "prototipal", yang tampaknya lebih akurat tetapi hanya menggelindingkan lidah sama sekali tidak baik. :-)
sumber
ngInclude
. Atau lakukan itu sebagai bagian dari bangunan Anda. Banyak pilihan!Kebijakan dan pengalaman pribadi saya:
Terisolasi: kotak pasir pribadi
Saya ingin membuat banyak metode dan variabel lingkup yang HANYA digunakan oleh arahan saya dan tidak pernah dilihat atau diakses langsung oleh pengguna. Saya ingin memasukkan daftar putih data lingkup apa yang tersedia untuk saya. Saya dapat menggunakan transklusi untuk memungkinkan pengguna untuk melompat kembali pada lingkup induknya (tidak terpengaruh) . Saya TIDAK ingin variabel dan metode saya dapat diakses pada anak-anak yang ditransklusikan.
Anak: subbagian konten
Saya ingin membuat metode dan variabel lingkup yang BISA diakses oleh pengguna, tetapi tidak relevan dengan cakupan di sekitarnya (saudara dan orang tua) di luar konteks arahan saya. Saya juga ingin membiarkan SEMUA data cakupan induknya mengalir turun secara transparan.
Tidak ada: arahan sederhana, hanya baca
Saya tidak benar-benar perlu mengacaukan metode atau variabel ruang lingkup. Saya mungkin melakukan sesuatu yang tidak ada hubungannya dengan cakupan (seperti menampilkan plugin jQuery sederhana, validasi, dll).
Catatan
ng-model=$parent.myVal
(anak) ataungModel: '='
(mengisolasi).require: '^ngModel'
untuk melihat elemen induk.sumber
Setelah menulis banyak arahan, saya memutuskan untuk menggunakan
isolated
lingkup yang lebih sedikit . Meskipun itu keren dan Anda merangkum data dan pastikan untuk tidak membocorkan data ke lingkup induk, itu sangat membatasi jumlah arahan yang dapat Anda gunakan bersama. Begitu,Jika arahan yang akan Anda tulis akan berlaku sepenuhnya dan Anda tidak akan membaginya dengan arahan lain, pilihlah ruang lingkup yang terisolasi . (seperti komponen, Anda cukup mencolokkannya, dengan tidak banyak penyesuaian untuk pengembang akhir) (itu menjadi sangat rumit ketika Anda mencoba menulis sub-elemen yang memiliki arahan di dalamnya)
Jika direktif Anda akan menulis akan hanya membuat manipulasi dom yang tidak memerlukan keadaan internal lingkup, atau perubahan lingkup eksplisit (sebagian besar hal-hal yang sangat sederhana); pergi tanpa ruang lingkup baru . (seperti
ngShow
,ngMouseHover
,ngClick
,ngRepeat
)Jika arahan yang akan Anda tulis perlu mengubah beberapa elemen dalam cakupan induk, tetapi juga perlu menangani beberapa kondisi internal, gunakan lingkup anak baru . (seperti
ngController
)Pastikan untuk memeriksa kode sumber untuk arahan: https://github.com/angular/angular.js/tree/master/src/ng/directive
Ini sangat membantu tentang cara berpikir tentang mereka
sumber
require
, sehingga menjaga arahan Anda masih terpisah. Jadi bagaimana membatasi kemungkinan? Itu bahkan membuat arahan lebih spesifik (jadi nyatakan apa yang Anda andalkan). Jadi saya hanya akan meninggalkan satu aturan: jika direktif Anda memiliki status atau memerlukan beberapa data dari ruang lingkup di mana ia digunakan - gunakan ruang lingkup yang terisolasi. Kalau tidak, jangan gunakan lingkup. Dan tentang "cakupan anak" - Saya juga menulis cukup banyak arahan dan tidak pernah membutuhkan fitur ini. Jika "perlu mengubah beberapa elemen dalam lingkup induk" - gunakan binding.$parent
hack kotor ). Jadi sebenarnya "cakupan anak" untuk arahan adalah sesuatu yang sepertinya harus digunakan cukup belakang - sepertingRepeat
yang menciptakan lingkup anak baru untuk setiap item untuk diulang (tetapi juga membuatnya menggunakanscope.$new();
dan tidakscope: true
.ngClick
dll.) Membutuhkan menciptakan semacam decoupling, saya setuju, tetapi Anda masih perlu mengetahui arahan orang tua. Kecuali itu seperti komponen , saya menentang pergi untuk isolasi. Arahan (setidaknya, sebagian besar dari mereka) dimaksudkan untuk dapat digunakan kembali dan isolasi mematahkan ini.Hanya berpikir saya akan menambahkan pemahaman saya saat ini dan bagaimana hubungannya dengan konsep JS lainnya.
Default (mis. Tidak dinyatakan atau ruang lingkup: false)
Secara filosofis ini setara dengan menggunakan variabel global. Arahan Anda dapat mengakses semua yang ada di pengontrol induk tetapi juga memengaruhi mereka dan terpengaruh pada saat yang sama.
cakupan:{}
Ini seperti modul, apa pun yang ingin digunakan perlu diteruskan secara eksplisit. Jika SETIAP arahan yang Anda gunakan adalah ruang lingkup isolat, itu bisa setara dengan membuat SETIAP file JS Anda menulis modul sendiri dengan banyak overhead dalam menyuntikkan semua dependensi.
ruang lingkup: anak
Ini adalah jalan tengah antara variabel global dan passthrough eksplisit. Ini mirip dengan rantai prototipe javascript dan hanya memperpanjang Anda salinan lingkup induknya. Jika Anda membuat ruang lingkup isolat dan meneruskan setiap atribut dan fungsi dari lingkup induk, itu secara fungsional setara dengan ini.
Kuncinya adalah bahwa arahan APAPUN dapat ditulis dengan cara APA SAJA. Deklarasi ruang lingkup yang berbeda hanya ada untuk membantu Anda mengatur. Anda dapat membuat semuanya modul, atau Anda bisa menggunakan semua variabel global dan sangat berhati-hati. Untuk kemudahan perawatan, lebih baik memodulasi logika Anda menjadi bagian-bagian yang logis secara koheren. Ada keseimbangan antara padang rumput terbuka dan rumah tahanan tertutup. Alasan ini rumit saya percaya adalah bahwa ketika orang belajar tentang ini mereka pikir mereka belajar tentang bagaimana arahan bekerja tetapi sebenarnya mereka belajar tentang kode / logika organisasi.
Hal lain yang membantu saya mengetahui bagaimana arahan bekerja adalah belajar tentang ngInclude. ngInclude membantu Anda memasukkan sebagian html. Ketika saya pertama kali mulai menggunakan arahan, saya menemukan bahwa Anda dapat menggunakan opsi templat untuk mengurangi kode Anda, tetapi saya tidak benar-benar melampirkan logika apa pun.
Tentu saja antara arahan sudut dan pekerjaan tim sudut-ui saya belum harus membuat arahan saya sendiri yang melakukan sesuatu yang substansial sehingga pandangan saya tentang ini mungkin benar-benar salah.
sumber
Saya setuju dengan Umur. Secara teori, ruang lingkup terisolasi terdengar indah dan "portabel," tetapi dalam membangun aplikasi saya untuk melibatkan fungsionalitas non-sepele, saya menemukan perlunya memasukkan beberapa arahan (beberapa bersarang di dalam yang lain atau menambahkan atribut kepada mereka) untuk sepenuhnya menulis di saya HTML sendiri, yang merupakan tujuan dari Bahasa Spesifik Domain.
Pada akhirnya, itu terlalu aneh untuk meneruskan setiap nilai global atau bersama ke rantai dengan beberapa atribut pada setiap permintaan DOM dari arahan (seperti yang diperlukan dengan ruang lingkup yang terpisah). Tampaknya bodoh untuk berulang kali menulis semua itu di DOM dan rasanya tidak efisien, bahkan jika ini adalah objek bersama. Ini juga tidak perlu memperumit deklarasi direktif. Solusi menggunakan $ parent untuk "mencapai" dan mengambil nilai dari HTML direktif sepertinya Bentuk Sangat Buruk.
Saya juga akhirnya mengubah aplikasi saya untuk memiliki sebagian besar arahan lingkup anak dengan sangat sedikit isolat - hanya mereka yang tidak perlu mengakses APA SAJA dari orang tua selain dari apa yang dapat mereka lewati melalui atribut sederhana yang tidak berulang.
Setelah memimpikan impian Domain Specific Languages selama beberapa dekade sebelum ada hal seperti itu, saya gembira bahwa AngularJS menyediakan opsi ini dan saya tahu bahwa, karena lebih banyak pengembang yang bekerja di bidang ini, kita akan melihat beberapa aplikasi yang sangat keren yang juga mudah bagi arsitek mereka untuk menulis, memperluas, dan men-debug.
- D
sumber