Il semble y avoir pas mal de façons de communiquer entre les directives. Supposons que vous ayez des directives imbriquées, où les directives internes doivent communiquer quelque chose à l'extérieur (par exemple, elles ont été choisies par l'utilisateur).
<outer>
<inner></inner>
<inner></inner>
</outer>
Jusqu'à présent, j'ai 5 façons de le faire
require:
directive parent
La inner
directive peut exiger la outer
directive, qui peut exposer une méthode sur son contrôleur. Donc, dans la inner
définition
require: '^outer',
link: function(scope, iElement, iAttrs, outerController) {
// This can be passed to ng-click in the template
$scope.chosen = function() {
outerController.chosen(something);
}
}
Et dans le outer
contrôleur de la directive:
controller: function($scope) {
this.chosen = function(something) {
}
}
$emit
un événement
La inner
directive peut constituer $emit
un événement auquel elle outer
peut répondre via $on
. Donc, dans le inner
contrôleur de la directive:
controller: function($scope) {
$scope.chosen = function() {
$scope.$emit('inner::chosen', something);
}
}
et dans le outer
contrôleur de directives:
controller: function($scope) {
$scope.$on('inner::chosen, function(e, data) {
}
}
Exécuter une expression dans l'étendue parent, via &
L'élément peut se lier à une expression de la portée parent et l'exécuter à un moment approprié. Le HTML serait comme:
<outer>
<inner inner-choose="functionOnOuter(item)"></inner>
<inner inner-choose="functionOnOuter(item)"></inner>
</outer>
Donc, le inner
contrôleur a une fonction 'innerChoose' qu'il peut appeler
scope: {
'innerChoose': '&'
},
controller: function() {
$scope.click = function() {
$scope.innerChoose({item:something});
}
}
qui appellerait (dans ce cas) la fonction 'functionOnOuter' sur le outer
champ d'application de la directive:
controller: function($scope) {
$scope.functionOnOuter = function(item) {
}
}
Portée d'héritage sur une portée non isolée
Étant donné qu'il s'agit de contrôleurs imbriqués, l'héritage de la portée peut être utile et la directive interne peut simplement appeler n'importe quelle fonction de la chaîne de la portée, tant qu'elle n'a pas de portée isolée. Donc dans la inner
directive:
// scope: anything but a hash {}
controller: function() {
$scope.click = function() {
$scope.functionOnOuter(something);
}
}
Et dans la outer
directive:
controller: function($scope) {
$scope.functionOnOuter = function(item) {
}
}
Par service injecté à l'intérieur et à l'extérieur
Un service peut être injecté dans les deux directives, de sorte qu'ils puissent avoir un accès direct au même objet ou appeler des fonctions pour notifier le service, et peut-être même s'enregistrer pour être notifié, dans un système de publication / sous-système. Cela n'exige pas que les directives soient imbriquées.
Question : Quels sont les inconvénients et avantages potentiels des uns par rapport aux autres?