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?
la source
Réponses:
Ma préférence va à la définition d'un
&
attribut dans la portée de la directive, principalement parce que je considère lascope: {}
définition d'une directive comme son API. Il est beaucoup plus facile d'examiner une définition d'attribut de portée pour voir les informations nécessaires au bon fonctionnement de la directive que de rechercher des fonctions de liaison et de contrôleur pour$emit
les événements d, les fonctions de portée héritées ou utilisées dans les contrôleurs injectés.la source
Mon avis:
Les services constituent le moyen privilégié de partager le comportement / les données entre modules, directives et contrôleurs. Les directives sont des éléments isolés pouvant être imbriqués ou non. Les contrôleurs doivent rester autant que possible un modèle de vue. Dans l'idéal, aucune logique métier ne devrait s'y retrouver.
Alors:
Lorsque vous commencez à les lier ensemble en accédant aux fonctions d'étendue parent, je pense que vous risquez de les coupler beaucoup trop fort et de rendre toute l'application illisible et les composants non réutilisables. Lorsque vous découplez ces données ou comportements partagés dans un service, vous avez l'avantage de réutiliser l'intégralité des directives avec des données / comportements différents, même en déterminant le service à utiliser au moment de l'exécution. C’est en quoi consiste l’injection de dépendance.
la source