Wydaje się, że istnieje wiele sposobów komunikowania się między dyrektywami. Powiedzmy, że masz zagnieżdżone dyrektywy, w których wewnętrzne dyrektywy muszą komunikować coś z zewnętrznymi (np. Zostało wybrane przez użytkownika).
<outer>
<inner></inner>
<inner></inner>
</outer>
Do tej pory mam 5 sposobów na zrobienie tego
require:
dyrektywa nadrzędna
inner
Dyrektywa może wymagać outer
dyrektywę, która może narazić jakiś sposób na jego sterownika. Więc w inner
definicji
require: '^outer',
link: function(scope, iElement, iAttrs, outerController) {
// This can be passed to ng-click in the template
$scope.chosen = function() {
outerController.chosen(something);
}
}
A w outer
kontrolerze dyrektywy:
controller: function($scope) {
this.chosen = function(something) {
}
}
$emit
zdarzenie
inner
Dyrektywy może $emit
zdarzenie, którego outer
dyrektywa może odpowiedzieć, poprzez $on
. Zatem w inner
kontrolerze dyrektywy:
controller: function($scope) {
$scope.chosen = function() {
$scope.$emit('inner::chosen', something);
}
}
a w outer
dyrektywach kontroler:
controller: function($scope) {
$scope.$on('inner::chosen, function(e, data) {
}
}
Wykonaj wyrażenie w zakresie nadrzędnym za pośrednictwem &
Element może powiązać się z wyrażeniem w zakresie nadrzędnym i wykonać go w odpowiednim punkcie. HTML wyglądałby tak:
<outer>
<inner inner-choose="functionOnOuter(item)"></inner>
<inner inner-choose="functionOnOuter(item)"></inner>
</outer>
Tak więc inner
kontroler ma funkcję „InternalChoose”, którą może wywołać
scope: {
'innerChoose': '&'
},
controller: function() {
$scope.click = function() {
$scope.innerChoose({item:something});
}
}
która wywołałaby (w tym przypadku) funkcję „functionOnOuter” w zakresie outer
dyrektywy:
controller: function($scope) {
$scope.functionOnOuter = function(item) {
}
}
Dziedziczenie zakresu w zakresie nieizolowanym
Biorąc pod uwagę, że są to kontrolery zagnieżdżone, dziedziczenie zakresu może działać, a wewnętrzna dyrektywa może po prostu wywoływać dowolne funkcje w łańcuchu zasięgu, o ile nie ma izolowanego zakresu). Tak więc w inner
dyrektywie:
// scope: anything but a hash {}
controller: function() {
$scope.click = function() {
$scope.functionOnOuter(something);
}
}
A w outer
dyrektywie:
controller: function($scope) {
$scope.functionOnOuter = function(item) {
}
}
Przez usługę wstrzykuje się zarówno wewnętrzną, jak i zewnętrzną
Usługę można wprowadzić do obu dyrektyw, aby mogły mieć bezpośredni dostęp do tego samego obiektu lub wywoływać funkcje w celu powiadomienia usługi, a może nawet zarejestrować się, aby otrzymać powiadomienie, w systemie pub / sub. Nie wymaga to zagnieżdżania dyrektyw.
Pytanie : Jakie są potencjalne wady i zalety każdego z nich?
źródło
Odpowiedzi:
Preferuję definiowanie
&
atrybutu w zakresie dyrektywy przede wszystkim dlatego, że uważamscope: {}
definicję dyrektywy za jej interfejs API. O wiele łatwiej jest spojrzeć na definicję atrybutu zasięgu, aby zobaczyć, jakie informacje musi funkcjonować dyrektywa, niż przeszukać funkcje łącza i kontrolera pod kątem$emit
zdarzeń, dziedziczonych funkcji zakresu lub funkcji używanych w kontrolerach wstrzykiwanych.źródło
Moja opinia:
Usługi są preferowanym sposobem udostępniania zachowania / danych między modułami / dyrektywami / kontrolerami. Dyrektywy to pojedyncze rzeczy, które można zagnieżdżać lub nie. Administratorzy powinni trzymać się modelu wyświetlania tak bardzo, jak to tylko możliwe, idealnie, gdyby nie logika biznesowa.
Więc:
Kiedy zaczynasz je łączyć ze sobą, uzyskując dostęp do funkcji zakresu nadrzędnego, myślę, że ryzykujesz ich zbyt mocnym połączeniem i sprawia, że cała aplikacja jest nieczytelna, a części nie można ponownie użyć. Po odsprzęgnięciu współużytkowanych danych lub zachowania w usłudze zyskujesz możliwość ponownego wykorzystania całych dyrektyw z różnymi danymi / zachowaniem, nawet określając usługę, która ma być używana w czasie wykonywania. O to właśnie chodzi w iniekcji zależności.
źródło