Comunicazione tra direttive annidate

58

Sembra che ci siano diversi modi di comunicare tra le direttive. Supponiamo che tu abbia direttive nidificate, in cui le direttive interne devono comunicare qualcosa all'esterno (ad esempio è stato scelto dall'utente).

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

Finora ho 5 modi per farlo

require: direttiva genitore

La direttiva inner può richiedere la direttiva outer , che può esporre qualche metodo sul suo controller. Quindi nella definizione inner

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 controller della direttiva outer :

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

$emit evento

La direttiva inner può $emit un evento, a cui la direttiva outer può rispondere, tramite $on . Quindi nel controller della direttiva inner :

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

e nel controller outer directives:

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

Esegui 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 controller inner 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" sull'ambito della direttiva outer :

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

Ambito dell'eredità 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, a condizione che non abbia un ambito isolato). Quindi nella direttiva inner :

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

E nella direttiva outer :

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 anche registrarsi per essere notificati, in un sistema di pubblicazione / sottosistema. Questo non richiede che le direttive siano nidificate.

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

    
posta Michal Charemza 03.01.2014 - 11:21
fonte

2 risposte

7

La mia preferenza è di definire un attributo & nello scope direttiva principalmente perché visualizzo la definizione scope: {} di una direttiva come sua API. È molto più semplice esaminare la definizione di un attributo di ambito per vedere quali informazioni la direttiva deve funzionare correttamente rispetto a setacciare le funzioni di link e controller per $emit 'd eventi, funzioni dell'ambito ereditato o funzioni utilizzate nei controller iniettati.

    
risposta data 09.03.2014 - 13:58
fonte
1

La mia opinione:

I servizi sono il modo preferito di condividere comportamenti / dati tra moduli / direttive / controllori. Le direttive sono cose isolate che possono essere annidate o meno. I controllori dovrebbero limitarsi a essere un viewmodel il più possibile, idealmente nessuna logica di business dovrebbe finire lì dentro.

Quando inizi a collegarli insieme accedendo alle funzioni dello scope genitore, ritengo che rischi di accoppiarli troppo duramente e rendere l'intera applicazione illeggibile e componenti non riutilizzabili. Quando si disaccoppiano i dati condivisi o il comportamento in un servizio, si ha il vantaggio di riutilizzare tutte le direttive con dati / comportamenti diversi, anche determinando il servizio da utilizzare in fase di runtime. Qual è l'aspetto dell'iniezione di dipendenza.

    
risposta data 27.01.2016 - 11:06
fonte

Leggi altre domande sui tag