Mam dyrektywę formularza, która używa określonego callback
atrybutu z izolowanym zakresem:
scope: { callback: '&' }
Znajduje się wewnątrz an, ng-repeat
więc wyrażenie, które przekazuję, zawiera id
obiekt jako argument funkcji zwrotnej:
<directive ng-repeat = "item in stuff" callback = "callback(item.id)"/>
Kiedy skończyłem pracę z dyrektywą, wywołuje $scope.callback()
ona funkcję kontrolera. W większości przypadków jest to w porządku i to wszystko, co chcę zrobić, ale czasami chciałbym dodać kolejny argument z directive
samego wnętrza .
Czy istnieje wyrażenie kątowe, które pozwoliłoby na to $scope.callback(arg2)
:, skutkując callback
wywołaniem z arguments = [item.id, arg2]
?
Jeśli nie, jaki jest najlepszy sposób na zrobienie tego?
Odkryłem, że to działa:
<directive
ng-repeat = "item in stuff"
callback = "callback"
callback-arg="item.id"/>
Z
scope { callback: '=', callbackArg: '=' }
i wywołanie dyrektywy
$scope.callback.apply(null, [$scope.callbackArg].concat([arg2, arg3]) );
Ale nie sądzę, że jest to szczególnie schludne i wymaga umieszczenia dodatkowych rzeczy w izolowanym zakresie.
Czy jest lepszy sposób?
Plunker zabaw tutaj (otwórz konsolę).
źródło
ng
API, na przykładng-click="someFunction()"
jest wyrażeniem, którego wynikiem jest wykonanie funkcji.$scope.callback
jest ustawiana przezcallback="someFunction"
atrybut iscope: { callback: '=' }
właściwość obiektu definicji dyrektywy.$scope.callback
jest funkcją, która zostanie wywołana w późniejszym terminie. Rzeczywista wartość atrybutu jest oczywiście ciągiem znaków - tak jest zawsze w przypadku HTML.Odpowiedzi:
Jeśli zadeklarujesz swoje wywołanie zwrotne, jak wspomniano w @ lex82 like
Możesz wywołać metodę wywołania zwrotnego w zakresie dyrektywy z mapą obiektów i poprawnie wykona powiązanie. Lubić
bez wymagania $ parse. Zobacz moje skrzypce (dziennik konsoli) http://jsfiddle.net/k7czc/2/
Aktualizacja : w dokumentacji jest mały przykład :
źródło
Nie ma nic złego w innych odpowiedziach, ale używam następującej techniki podczas przekazywania funkcji w atrybucie dyrektywy.
Nie używaj nawiasów, jeśli dołączasz dyrektywę do kodu HTML:
Następnie „rozpakuj” funkcję w linku lub kontrolerze dyrektywy. Oto przykład:
Krok „rozpakowywania” umożliwia wywołanie funkcji przy użyciu bardziej naturalnej składni. Zapewnia również, że dyrektywa działa poprawnie, nawet gdy jest zagnieżdżona w innych dyrektywach, które mogą przekazać tę funkcję. Jeśli nie rozpakowałeś, to jeśli masz taki scenariusz:
Wtedy w swojej wewnętrznej dyrektywie otrzymałeś coś takiego:
Co by się nie udało w innych scenariuszach zagnieżdżania.
Zaadaptowałem tę technikę z doskonałego artykułu Dana Wahlina na http://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-3-isolate-scope-and-function-parameters
Dodałem krok rozpakowywania, aby wywoływanie funkcji było bardziej naturalne i aby rozwiązać problem zagnieżdżenia, który napotkałem w projekcie.
źródło
this
wskaźnika wewnątrz metody wywołania zwrotnego, ponieważ korzysta z zakresu dyrektywy. Używam Typescript i moje wywołanie zwrotne wygląda następująco:public validateFirstName(firstName: string, fieldName: string): ng.IPromise<boolean> { var deferred = this.mQService.defer<boolean>(); ... .then(() => deferred.resolve(true)) .catch((msg) => { deferred.reject(false); }); return deferred.promise; }
W dyrektywie (
myDirective
):W szablonie dyrektywy:
W źródle:
... gdzie
myFunction
jest zdefiniowane w kontrolerze.Zauważ, że
param
w dyrektywie szablon wiąże się starannieparam
ze źródłem i jest ustawiony naitem
.Aby wywołać z
link
właściwości dyrektywy („z jej wnętrza”), użyj bardzo podobnego podejścia:źródło
Tak, jest lepszy sposób: możesz użyć usługi $ parse w swojej dyrektywie, aby ocenić wyrażenie w kontekście zakresu nadrzędnego, jednocześnie wiążąc określone identyfikatory w wyrażeniu z wartościami widocznymi tylko w dyrektywie:
Dodaj tę linię do funkcji link dyrektywy, gdzie możesz uzyskać dostęp do atrybutów dyrektywy.
Twój atrybut callback może być wtedy ustawiony tak, jak
callback = "callback(item.id, arg2)"
ponieważ arg2 jest powiązany z yourSecondArgument przez usługę $ parse wewnątrz dyrektywy. Dyrektywy takie jakng-click
umożliwiają dostęp do zdarzenia kliknięcia za pośrednictwem$event
identyfikatora wewnątrz wyrażenia przekazanego do dyrektywy przy użyciu dokładnie tego mechanizmu.Zauważ, że nie musisz tworzyć
callback
elementu członkowskiego zakresu izolowanego za pomocą tego rozwiązania.źródło
scope.$parent
sprawia, że dyrektywa jest „nieszczelna” - za dużo „wie” o świecie zewnętrznym, czego nie powinien posiadać dobrze zaprojektowany komponent hermetyzowany.Dla mnie zadziałało:
w dyrektywie zadeklaruj to następująco:
W szablonie dyrektywy użyj go w następujący sposób:
A kiedy używasz dyrektywy, przekaż funkcję w ten sposób:
Przekazujesz funkcję przez jej deklarację i jest ona wywoływana z dyrektywy, a parametry są wypełniane.
źródło