Comunicazione tra direttive nidificate


61

Sembrano esserci parecchi modi di comunicare tra le direttive. Supponi di avere delle direttive nidificate, in cui le direttive interne devono comunicare qualcosa all'esterno (ad esempio, è stata scelta dall'utente).

<outer>
  <inner></inner>
  <inner></inner>
</outer>

Finora ho 5 modi per farlo

require: direttiva principale

La innerdirettiva può richiedere la outerdirettiva, che può esporre un metodo sul suo controller. Quindi nella innerdefinizione

require: '^outer',
link: function(scope, iElement, iAttrs, outerController) {
   // This can be passed to ng-click in the template
   $scope.chosen = function() {
     outerController.chosen(something);
   }
}

E nel outercontroller della direttiva:

controller: function($scope) {
   this.chosen = function(something) {
   }
}

$emit evento

La innerdirettiva può $emitun evento, a cui la outerdirettiva può rispondere, tramite $on. Quindi nel innercontroller della direttiva:

controller: function($scope) {
  $scope.chosen = function() {
    $scope.$emit('inner::chosen', something);
  }
}

e nel outerresponsabile delle direttive:

controller: function($scope) {
  $scope.$on('inner::chosen, function(e, data) {
  }
}

Eseguire l'espressione nell'ambito genitore, tramite &

L'elemento può associarsi a un'espressione nell'ambito genitore ed eseguirlo in un punto appropriato. L'HTML sarebbe come:

<outer>
  <inner inner-choose="functionOnOuter(item)"></inner>
  <inner inner-choose="functionOnOuter(item)"></inner>
</outer>

Quindi il innercontroller ha una funzione 'innerChoose' che può chiamare

scope: {
  'innerChoose': '&'
},
controller: function() {
  $scope.click = function() {
    $scope.innerChoose({item:something});
  }
}

che chiamerebbe (in questo caso) la funzione 'functionOnOuter' nell'ambito della outerdirettiva:

controller: function($scope) {
  $scope.functionOnOuter = function(item) {
  }
}

Eredità dell'ambito su ambito non isolato

Dato che si tratta di controller nidificati, l'ereditarietà dell'ambito può essere al lavoro e la direttiva interna può semplicemente chiamare qualsiasi funzione nella catena dell'ambito, purché non abbia un ambito isolato). Quindi nella innerdirettiva:

// scope: anything but a hash {}
controller: function() {
  $scope.click = function() {
    $scope.functionOnOuter(something);
  }
}

E nella outerdirettiva:

controller: function($scope) {
  $scope.functionOnOuter = function(item) {
  }
}

Per servizio iniettato sia all'interno che all'esterno

Un servizio può essere iniettato in entrambe le direttive, in modo che possano avere accesso diretto allo stesso oggetto o chiamare funzioni per notificare il servizio e magari registrarsi per ricevere una notifica in un pub / sottosistema. Ciò non richiede che le direttive siano nidificate.

Domanda : quali sono i potenziali svantaggi e vantaggi di ciascuno rispetto agli altri?


5
Non posso credere di non aver visto questa domanda prima d'ora. Apprezzo tutte le opzioni che hai fornito. Se non l'hai già fatto, hai pensato di pubblicare questa domanda su StackOverflow? Mi aspetterei che otterrebbe molta più trazione su StackOverflow.
Mike Barlow - BarDev

Risposte:


7

La mia preferenza è quella di definire un &attributo nell'ambito della direttiva principalmente perché vedo la scope: {}definizione di una direttiva come sua API. È molto più semplice guardare una definizione di attributo dell'ambito per vedere quali informazioni la direttiva ha bisogno per funzionare correttamente piuttosto che per scrutare le funzioni di collegamento e controller per $emiteventi, funzioni dell'ambito ereditate o funzioni utilizzate all'interno dei controller iniettati.


1

La mia opinione:

I servizi sono il modo preferito di condividere comportamenti / dati tra moduli / direttive / controller. Le direttive sono cose isolate che possono essere nidificate o meno. I controller dovrebbero attenersi a essere un modello di visualizzazione il più possibile, idealmente nessuna logica aziendale dovrebbe finire lì.

Così:

Quando inizi a collegarli insieme accedendo alle funzioni dell'ambito padre, penso che rischi di accoppiarli troppo duramente e rendere illeggibile l'intera applicazione e i componenti non riutilizzabili. Quando si disaccoppiano quei dati o comportamenti condivisi in un servizio, si ha il vantaggio di riutilizzare le direttive complete con dati / comportamenti diversi, determinando persino il servizio da utilizzare in fase di esecuzione. Ecco cos'è l'iniezione di dipendenza.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.