Comunicação entre diretivas aninhadas

58

Parece haver algumas maneiras de se comunicar entre diretivas. Digamos que você tenha diretivas aninhadas, em que as diretivas internas devem comunicar algo ao exterior (por exemplo, ele foi escolhido pelo usuário).

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

Até agora eu tenho 5 maneiras de fazer isso

require: parent directive

A diretiva inner pode exigir a diretiva outer , que pode expor algum método em seu controlador. Então, na definição 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 no controlador da diretiva outer :

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

$emit event

A diretiva inner pode $emit um evento, ao qual a diretiva outer pode responder, via $on . Portanto, no controlador da diretiva inner :

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

e no controlador de diretivas outer :

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

Executa a expressão no escopo pai, via &

O item pode se ligar a uma expressão no escopo pai e executá-lo em um ponto apropriado. O HTML seria como:

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

Portanto, o controlador inner tem uma função 'innerChoose' que pode chamar

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

que chamaria (neste caso) a função 'functionOnOuter' no escopo da diretiva outer :

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

Herança do escopo no escopo não isolado

Dado que estes são controladores aninhados, a herança do escopo pode estar no trabalho, e a diretiva interna pode apenas chamar qualquer função na cadeia do escopo, desde que não tenha um escopo isolado). Então, na diretiva inner :

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

E na diretiva outer :

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

Por serviço injetado no interior e exterior

Um serviço pode ser injetado em ambas as diretivas, para que eles possam ter acesso direto ao mesmo objeto, ou chamar funções para notificar o serviço, e talvez até se registrarem para serem notificados, em um sistema de pub / sub. Isso não requer que as diretivas sejam aninhadas.

Pergunta : Quais são os potenciais inconvenientes e vantagens de cada um sobre os outros?

    
por Michal Charemza 03.01.2014 / 11:21
fonte

2 respostas

7

Minha preferência é definir um atributo & no escopo da diretiva principalmente porque vejo a definição scope: {} de uma diretiva como sua API. É muito mais fácil olhar para uma definição de atributo de escopo para ver quais informações a diretiva precisa para funcionar adequadamente do que limpar funções de link e controlador para eventos $emit 'd, funções de escopo herdadas ou funções usadas em controladores injetados.

    
por 09.03.2014 / 13:58
fonte
1

Minha opinião:

Os serviços são a maneira preferida de compartilhar comportamento / dados em módulos / diretivas / controladores. Diretivas são coisas isoladas que podem ser aninhadas ou não. Os controladores devem manter-se como um modelo de visão tanto quanto possível, idealmente, nenhuma lógica de negócios deve acabar aí.

Então:

Quando você começa a conectá-los acessando as funções do escopo pai, acho que corre o risco de acoplá-los de maneira muito difícil e tornar a aplicação inteira ilegível e os componentes não reutilizáveis. Quando você dissocia esses dados compartilhados ou comportamento em um serviço, você tem o benefício de reutilizar as diretivas inteiras com dados / comportamento diferentes, mesmo determinando o serviço a ser usado no tempo de execução. Qual é o significado da injeção de dependência.

    
por 27.01.2016 / 11:06
fonte