Dalam kasus di mana Anda memiliki beberapa arahan pada elemen DOM tunggal dan di mana urutan penerapannya penting, Anda bisa menggunakan priority
properti untuk memesan aplikasi mereka. Angka yang lebih tinggi dijalankan terlebih dahulu. Prioritas default adalah 0 jika Anda tidak menentukan satu.
EDIT : setelah diskusi, inilah solusi lengkap untuk bekerja. Kuncinya adalah untuk menghapus atribut : element.removeAttr("common-things");
, dan juga element.removeAttr("data-common-things");
(dalam kasus pengguna menentukan data-common-things
di html)
angular.module('app')
.directive('commonThings', function ($compile) {
return {
restrict: 'A',
replace: false,
terminal: true, //this setting is important, see explanation below
priority: 1000, //this setting is important, see explanation below
compile: function compile(element, attrs) {
element.attr('tooltip', '{{dt()}}');
element.attr('tooltip-placement', 'bottom');
element.removeAttr("common-things"); //remove the attribute to avoid indefinite loop
element.removeAttr("data-common-things"); //also remove the same attribute with data- prefix in case users specify data-common-things in the html
return {
pre: function preLink(scope, iElement, iAttrs, controller) { },
post: function postLink(scope, iElement, iAttrs, controller) {
$compile(iElement)(scope);
}
};
}
};
});
Plunker yang berfungsi tersedia di: http://plnkr.co/edit/Q13bUt?p=preview
Atau:
angular.module('app')
.directive('commonThings', function ($compile) {
return {
restrict: 'A',
replace: false,
terminal: true,
priority: 1000,
link: function link(scope,element, attrs) {
element.attr('tooltip', '{{dt()}}');
element.attr('tooltip-placement', 'bottom');
element.removeAttr("common-things"); //remove the attribute to avoid indefinite loop
element.removeAttr("data-common-things"); //also remove the same attribute with data- prefix in case users specify data-common-things in the html
$compile(element)(scope);
}
};
});
DEMO
Penjelasan mengapa kita harus mengatur terminal: true
dan priority: 1000
(angka tinggi):
Ketika DOM siap, sudut berjalan DOM untuk mengidentifikasi semua arahan terdaftar dan menyusun arahan satu per satu berdasarkan priority
jika arahan ini berada di elemen yang sama . Kami menetapkan prioritas arahan khusus kami ke angka yang tinggi untuk memastikan bahwa arahan tersebut akan dikompilasi terlebih dahulu dan terminal: true
, arahan lainnya akan dilewati setelah arahan ini dikompilasi.
Ketika arahan khusus kami dikompilasi, itu akan memodifikasi elemen dengan menambahkan arahan dan menghapus sendiri dan menggunakan layanan $ compile untuk mengkompilasi semua arahan (termasuk yang dilewati) .
Jika kami tidak menetapkan terminal:true
dan priority: 1000
, ada kemungkinan beberapa arahan dikompilasi sebelum arahan adat kami. Dan ketika arahan khusus kami menggunakan $ compile untuk mengkompilasi elemen => kompilasi lagi arahan yang sudah dikompilasi. Ini akan menyebabkan perilaku yang tidak dapat diprediksi terutama jika arahan yang dikompilasi sebelum arahan khusus kami telah mengubah DOM.
Untuk informasi lebih lanjut tentang prioritas dan terminal, lihat Bagaimana memahami `terminal` dari direktif?
Contoh dari arahan yang juga memodifikasi template adalah ng-repeat
(priority = 1000), ketika ng-repeat
dikompilasi, ng-repeat
buat salinan dari elemen template sebelum arahan lain diterapkan .
Berkat komentar @ Izhaki, berikut ini adalah referensi ke ngRepeat
kode sumber: https://github.com/angular/angular.js/blob/master/src/ng/directive/ngRepeat.js
RangeError: Maximum call stack size exceeded
seperti yang terus dikompilasi selamanya.element.removeAttr("common-datepicker");
untuk menghindari loop yang tidak terbatas.replace: false
,terminal: true
,priority: 1000
; kemudian atur atribut yang diinginkan dalamcompile
fungsi dan hapus atribut direktif kami. Akhirnya, dalampost
fungsi yang dikembalikan olehcompile
, panggil$compile(element)(scope)
. Elemen akan dikompilasi secara teratur tanpa arahan khusus tetapi dengan atribut yang ditambahkan. Apa yang saya coba capai adalah tidak menghapus arahan khusus dan menangani semua ini dalam satu proses: sepertinya ini tidak bisa dilakukan. Silakan lihat plnkr yang diperbarui: plnkr.co/edit/Q13bUt?p=preview .common-things
atribut Anda bisa melewati parameter maxPriority ke perintah kompilasi:$compile(element, null, 1000)(scope);
Anda benar-benar dapat menangani semua ini hanya dengan tag templat sederhana. Lihat http://jsfiddle.net/m4ve9/ untuk contoh. Perhatikan bahwa saya sebenarnya tidak memerlukan properti kompilasi atau tautan pada definisi super-direktif.
Selama proses kompilasi, Angular menarik nilai template sebelum kompilasi, sehingga Anda dapat melampirkan arahan lebih lanjut di sana dan Angular akan menanganinya untuk Anda.
Jika ini adalah arahan super yang perlu mempertahankan konten internal asli, Anda dapat menggunakannya
transclude : true
dan mengganti bagian dalamnya<ng-transclude></ng-transclude>
Semoga itu bisa membantu, beri tahu saya jika ada sesuatu yang tidak jelas
Alex
sumber
input
tag, tapi saya ingin membuatnya berfungsi untuk elemen apa pun, sepertidiv
s atauselect
s.element
danattrs
meneruskan. Butuh waktu lama untuk menyelesaikannya, dan saya belum melihatnya menggunakannya di mana pun - tetapi tampaknya berfungsi dengan baik: stackoverflow.com/a/20137542/1455709Inilah solusi yang menggerakkan arahan yang perlu ditambahkan secara dinamis, ke tampilan dan juga menambahkan beberapa logika kondisional opsional (dasar). Ini menjaga arahan tetap bersih tanpa logika kode-keras.
Arahan mengambil array objek, masing-masing objek berisi nama direktif yang akan ditambahkan dan nilai untuk diteruskan (jika ada).
Saya berjuang untuk memikirkan use-case untuk arahan seperti ini sampai saya berpikir bahwa mungkin berguna untuk menambahkan beberapa logika kondisional yang hanya menambahkan arahan berdasarkan pada beberapa kondisi (meskipun jawaban di bawah ini masih dibuat-buat). Saya menambahkan opsional
if
properti yang harus mengandung nilai bool, ekspresi atau fungsi (misalnya didefinisikan dalam controller Anda) yang menentukan apakah arahan harus ditambahkan atau tidak.Saya juga menggunakan
attrs.$attr.dynamicDirectives
untuk mendapatkan deklarasi atribut yang tepat digunakan untuk menambahkan direktif (misalnyadata-dynamic-directive
,dynamic-directive
) tanpa nilai string hard-coding untuk memeriksa.Plunker Demo
sumber
Saya ingin menambahkan solusi saya karena yang diterima tidak bekerja untuk saya.
Saya perlu menambahkan arahan tetapi juga menjaga saya pada elemen.
Dalam contoh ini saya menambahkan arahan gaya-ng sederhana ke elemen. Untuk mencegah loop kompilasi yang tak terbatas dan memungkinkan saya untuk menjaga direktif saya, saya menambahkan cek untuk melihat apakah apa yang saya tambahkan ada sebelum mengkompilasi ulang elemen.
sumber
Coba simpan status dalam atribut pada elemen itu sendiri, seperti
superDirectiveStatus="true"
Sebagai contoh:
Saya harap ini membantu Anda.
sumber
Terjadi perubahan dari 1.3.x ke 1.4.x.
Di Angular 1.3.x ini berfungsi:
Sekarang dalam Angular 1.4.x kita harus melakukan ini:
(Dari jawaban yang diterima: https://stackoverflow.com/a/19228302/605586 dari Khanh TO).
sumber
Solusi sederhana yang bisa digunakan dalam beberapa kasus adalah membuat dan $ mengkompilasi pembungkus lalu menambahkan elemen asli Anda ke dalamnya.
Sesuatu seperti...
Solusi ini memiliki keuntungan bahwa hal itu tetap sederhana dengan tidak menyusun ulang elemen asli.
Ini tidak akan berfungsi jika salah satu direktif yang ditambahkan adalah
require
salah satu arahan elemen asli atau jika elemen asli memiliki posisi absolut.sumber