Nie mogę znaleźć sposobu na wywołanie funkcji z zakresu nadrzędnego z poziomu dyrektywy bez użycia zakresu izolowanego. Wiem, że jeśli używam zakresu izolowanego, mogę po prostu użyć „&” w izolowanym, aby uzyskać dostęp do funkcji w zakresie nadrzędnym, ale użycie zakresu izolowanego, gdy nie jest to konieczne, ma konsekwencje. Rozważ następujący kod HTML:
<button ng-hide="hideButton()" confirm="Are you sure?" confirm-action="doIt()">Do It</button>
W tym prostym przykładzie chcę wyświetlić okno dialogowe potwierdzenia JavaScript i wywołać funkcję doIt () tylko wtedy, gdy klikną „OK” w oknie dialogowym potwierdzenia. Jest to proste przy użyciu izolowanego zakresu. Dyrektywa wyglądałaby następująco:
.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();
}
});
}
};
})
Ale problem polega na tym, że ponieważ używam zakresu izolowanego, ng-hide w powyższym przykładzie nie jest już wykonywany względem zakresu nadrzędnego , ale raczej w zakresie izolowanym (ponieważ użycie zakresu izolowanego w dowolnej dyrektywie powoduje, że wszystkie dyrektywy tego elementu użyć izolowanego zakresu). Oto jsFiddle z powyższego przykładu, w którym ng-hide nie działa. (Zauważ, że w tych skrzypcach przycisk powinien się ukryć po wpisaniu „tak” w polu wprowadzania).
Alternatywą byłoby NIE stosowanie izolowanego zakresu , czego tak naprawdę tutaj chcę, ponieważ nie ma potrzeby izolowania zakresu tej dyrektywy. Jedyny problem, jaki mam, polega na tym , jak wywołać metodę w zakresie nadrzędnym, jeśli nie przekażę jej w zakresie izolowanym ?
Oto jsfiddle, w którym NIE używam izolowanego zasięgu, a ng-hide działa dobrze, ale oczywiście wywołanie confirmAction () nie działa i nie wiem, jak to zrobić.
Proszę zauważyć, że odpowiedź, której naprawdę szukam, to wywoływanie funkcji w zakresie zewnętrznym BEZ stosowania zakresu izolowanego. I nie jestem zainteresowany, aby ten dialog potwierdzający działał w inny sposób, ponieważ celem tego pytania jest ustalenie, jak wywoływać zakres zewnętrzny i nadal być w stanie sprawić, by inne dyrektywy działały przeciwko zakresowi nadrzędnemu.
Ewentualnie chciałbym usłyszeć o rozwiązaniach wykorzystujących zakres izolowany, jeśli inne dyrektywy będą nadal działać przeciwko zakresowi nadrzędnemu , ale nie sądzę, aby było to możliwe.
źródło
Odpowiedzi:
Ponieważ dyrektywa tylko wywołuje funkcję (a nie próbuje ustawić wartości właściwości), możesz użyć $ eval zamiast $ parse (z nieizolowanym zakresem):
Lub lepiej, po prostu użyj $ Apply , co spowoduje $ eval () ułoży swój argument przeciwko zakresowi:
Skrzypce
źródło
confirm-action="doIt(arg1)"
, a następnie ustawićscope.arg1
przed wywołaniem $ eval. Jednak prawdopodobnie czystsze byłoby użycie $ parse: stackoverflow.com/a/16200618/215945scope.$eval(attrs.confirmAction({arg1: 'blah'})
nie będzie działać. Będziesz musiał użyć $ parse z taką składnią.Chcesz skorzystać z usługi $ parse w AngularJS.
Na przykład:
Jest pewna pułapka związana z ustawieniem właściwości za pomocą $ parse, ale pozwolę ci przejść przez ten most, kiedy do niego dojdziesz.
źródło
scope:true
) nie działa, ponieważ dyrektywa w ogóle nie utworzy nowego zakresu, a zatemscope
właściwość, do której odwołujesz się wlink
funkcji, jest dokładnie tym samym zakresem, co poprzednio zakres „nadrzędny”.Jawnie wywołaj
hideButton
zakres nadrzędny.Oto skrzypce: http://jsfiddle.net/pXej2/5/
A oto zaktualizowany kod HTML:
źródło
Najpierw mała uwaga: w tym przypadku zakres administratora zewnętrznego nie jest nadrzędnym zakresem dyrektywy; Zakres zewnętrznej regulatora jest zakres dyrektywy. Innymi słowy, nazwy zmiennych użyte w dyrektywie będą wyszukiwane bezpośrednio w zakresie kontrolera.
Następnie pisanie
attrs.confirmAction()
nie działa, ponieważattrs.confirmAction
dla tego przyciskujest napisem
"doIt()"
, a nie możesz wywołać łańcucha, np"doIt()"()
.Twoje pytanie naprawdę brzmi:
W JavaScript wywołujesz funkcje głównie przy użyciu notacji kropkowej, na przykład:
Ale możesz też użyć notacji tablicowej:
Zwróć uwagę, że wartość indeksu jest ciągiem . Tak więc w swojej dyrektywie możesz po prostu zrobić to:
źródło