Parece que hay bastantes formas de comunicación entre directivas. Supongamos que tiene directivas anidadas, donde las directivas internas deben comunicar algo a las externas (por ejemplo, ha sido elegido por el usuario).
<outer>
<inner></inner>
<inner></inner>
</outer>
Hasta ahora tengo 5 formas de hacer esto
require:
directiva de padres
La inner
directiva puede requerir la outer
directiva, que puede exponer algún método en su controlador. Entonces en la inner
definición
require: '^outer',
link: function(scope, iElement, iAttrs, outerController) {
// This can be passed to ng-click in the template
$scope.chosen = function() {
outerController.chosen(something);
}
}
Y en el outer
controlador de la directiva:
controller: function($scope) {
this.chosen = function(something) {
}
}
$emit
evento
La inner
directiva puede $emit
un evento, al que la outer
directiva puede responder, a través de $on
. Entonces, en el inner
controlador de la directiva:
controller: function($scope) {
$scope.chosen = function() {
$scope.$emit('inner::chosen', something);
}
}
y en el outer
controlador de directivas:
controller: function($scope) {
$scope.$on('inner::chosen, function(e, data) {
}
}
Ejecute la expresión en el ámbito primario, a través de &
El elemento puede vincularse a una expresión en el ámbito primario y ejecutarlo en un punto apropiado. El HTML sería como:
<outer>
<inner inner-choose="functionOnOuter(item)"></inner>
<inner inner-choose="functionOnOuter(item)"></inner>
</outer>
Entonces el inner
controlador tiene una función 'innerChoose' a la que puede llamar
scope: {
'innerChoose': '&'
},
controller: function() {
$scope.click = function() {
$scope.innerChoose({item:something});
}
}
que llamaría (en este caso) la función 'functionOnOuter' en el outer
alcance de la directiva:
controller: function($scope) {
$scope.functionOnOuter = function(item) {
}
}
Herencia de alcance en alcance no aislado
Dado que estos son controladores anidados, la herencia del alcance puede estar en funcionamiento, y la directiva interna puede llamar a cualquier función en la cadena del alcance, siempre que no tenga un alcance aislado). Entonces en la inner
directiva:
// scope: anything but a hash {}
controller: function() {
$scope.click = function() {
$scope.functionOnOuter(something);
}
}
Y en la outer
directiva:
controller: function($scope) {
$scope.functionOnOuter = function(item) {
}
}
Por servicio inyectado en interior y exterior
Se puede inyectar un servicio en ambas directivas, para que puedan tener acceso directo al mismo objeto, o llamar a funciones para notificar el servicio, y tal vez incluso registrarse para recibir una notificación, en un sistema pub / subsistema. Esto no requiere que las directivas estén anidadas.
Pregunta : ¿Cuáles son los posibles inconvenientes y ventajas de cada uno sobre los demás?
fuente
Respuestas:
Prefiero definir un
&
atributo en el ámbito de la directiva principalmente porque veo lascope: {}
definición de una directiva como su API. Es mucho más fácil mirar una definición de atributo de alcance para ver qué información necesita la directiva para funcionar correctamente que para rastrear el enlace y las funciones del controlador para$emit
'd eventos, funciones de alcance heredadas o funciones utilizadas dentro de los controladores inyectados.fuente
Mi opinión:
Los servicios son la forma preferida de compartir comportamiento / datos entre módulos / directivas / controladores. Las directivas son cosas aisladas que se pueden anidar o no. Los controladores deben seguir siendo un modelo de vista tanto como puedan, idealmente, ninguna lógica de negocios debería terminar ahí.
Entonces:
Cuando comience a conectarlos entre sí accediendo a las funciones de alcance principal, creo que corre el riesgo de acoplarlos demasiado y hacer que toda la aplicación sea ilegible y los componentes no sean reutilizables. Cuando desacopla esos datos o comportamientos compartidos en un servicio, tiene la ventaja de reutilizar todas las directivas con diferentes datos / comportamientos, incluso determinando el servicio que se utilizará en tiempo de ejecución. De eso se trata la inyección de dependencia.
fuente