Saya tidak bisa menemukan cara untuk memanggil fungsi pada lingkup induk dari dalam direktif tanpa menggunakan lingkup terisolasi. Saya tahu bahwa jika saya menggunakan lingkup terisolasi saya hanya dapat menggunakan "&" dalam lingkup terisolasi untuk mengakses fungsi pada lingkup induk, tetapi menggunakan lingkup terisolasi ketika tidak diperlukan memiliki konsekuensi. Perhatikan HTML berikut ini:
<button ng-hide="hideButton()" confirm="Are you sure?" confirm-action="doIt()">Do It</button>
Dalam contoh sederhana ini, saya ingin menampilkan dialog konfirmasi JavaScript dan hanya memanggil doIt () jika mereka mengklik "OK" di dialog konfirmasi. Ini sederhana menggunakan ruang lingkup terisolasi. Arahannya akan terlihat seperti ini:
.directive('confirm', function () {
return {
restrict: 'A',
scope: {
confirm: '@',
confirmAction: '&'
},
link: function (scope, element, attrs) {
element.bind('click', function (e) {
if (confirm(scope.confirm)) {
scope.confirmAction();
}
});
}
};
})
Tapi masalahnya, karena saya menggunakan scope terisolir, ng-hide dalam contoh di atas tidak lagi dieksekusi terhadap lingkup induk , melainkan dalam lingkup terisolir (karena menggunakan lingkup terisolir pada sembarang direktif menyebabkan semua arahan pada elemen itu menjadi menggunakan ruang lingkup terisolasi). Berikut adalah jsFiddle dari contoh di atas di mana ng-hide tidak berfungsi. (Perhatikan bahwa di biola ini, tombolnya harus bersembunyi saat Anda mengetik "ya" di kotak masukan.)
Alternatifnya adalah TIDAK menggunakan cakupan yang terisolasi , yang sebenarnya adalah apa yang saya inginkan di sini karena tidak perlu ruang lingkup arahan ini untuk diisolasi. Satu-satunya masalah yang saya miliki adalah, bagaimana cara memanggil metode pada lingkup induk jika saya tidak meneruskannya pada lingkup yang terisolasi ?
Berikut adalah jsfiddle di mana saya TIDAK menggunakan scope terisolasi dan ng-hide berfungsi dengan baik, tetapi, tentu saja, panggilan ke confirmAction () tidak berfungsi, dan saya tidak tahu cara membuatnya berfungsi.
Harap dicatat, jawaban yang benar-benar saya cari adalah bagaimana memanggil fungsi di lingkup luar TANPA menggunakan lingkup terisolasi. Dan saya tidak tertarik untuk membuat dialog konfirmasi ini berfungsi dengan cara lain, karena inti dari pertanyaan ini adalah untuk mencari tahu cara melakukan panggilan ke lingkup luar dan masih dapat membuat perintah lain bekerja melawan lingkup induk.
Atau, saya akan tertarik untuk mendengar solusi yang menggunakan lingkup terisolasi jika arahan lain masih akan bekerja melawan lingkup induk , tetapi saya rasa ini tidak mungkin.
sumber
Jawaban:
Karena direktif hanya memanggil fungsi (dan tidak mencoba menyetel nilai pada properti), Anda dapat menggunakan $ eval alih-alih $ parse (dengan cakupan non-terisolasi):
Atau lebih baik, cukup gunakan $ apply , yang akan $ eval () menggunakan argumennya terhadap cakupan:
Biola
sumber
confirm-action="doIt(arg1)"
, dan kemudian menyetelscope.arg1
sebelum memanggil $ eval. Namun, mungkin akan lebih bersih jika menggunakan $ parse: stackoverflow.com/a/16200618/215945scope.$eval(attrs.confirmAction({arg1: 'blah'})
tidak akan berhasil. Anda perlu menggunakan $ parse dengan sintaks itu.Anda ingin menggunakan layanan $ parse di AngularJS.
Jadi untuk contoh Anda:
Ada hal yang harus dilakukan dengan menyetel properti menggunakan $ parse, tetapi saya akan membiarkan Anda menyeberangi jembatan itu ketika Anda sampai di sana.
sumber
scope:true
) yang berfungsi karena direktif tidak akan membuat cakupan baru sama sekali, dan dengan demikianscope
properti yang Anda rujuk dalamlink
fungsi tersebut memiliki cakupan yang sama persis dengan cakupan 'induk' sebelumnya.Panggil secara eksplisit
hideButton
lingkup induk.Ini biolanya: http://jsfiddle.net/pXej2/5/
Dan inilah HTML yang diperbarui:
sumber
Pertama, poin kecil: Dalam hal ini lingkup pengontrol luar bukanlah lingkup induk dari lingkup direktif; lingkup controller luar ini adalah ruang lingkup direktif ini. Dengan kata lain, nama variabel yang digunakan dalam direktif akan dicari secara langsung di lingkup pengontrol.
Selanjutnya, penulisan
attrs.confirmAction()
tidak berfungsi karenaattrs.confirmAction
untuk tombol ini,adalah string
"doIt()"
, dan Anda tidak dapat memanggil string, mis"doIt()"()
.Pertanyaan Anda sebenarnya adalah:
Di JavaScript, Anda kebanyakan memanggil fungsi menggunakan notasi titik, seperti ini:
Tetapi Anda juga bisa menggunakan notasi array:
Perhatikan bagaimana nilai indeks adalah string . Jadi, dalam arahan Anda, Anda cukup melakukan ini:
sumber