Diferença entre as funções 'controller', 'link' e 'compile' ao definir uma diretiva

393

Alguns lugares parecem usar a função do controlador para lógica de diretiva e outros usam o link. O exemplo de guias na página inicial angular usa controlador para um e link para outra diretiva. Qual é a diferença entre os dois?

user1558259
fonte
2
Talvez uma visão mais abrangente das funções de diretiva: Diretivas angulares - quando usar compilação, controlador, pré-link e pós-link .
Izhaki 07/07

Respostas:

635

Vou expandir um pouco sua pergunta e também incluir a função de compilação.

  • função de compilação - use para manipulação DOM do modelo (ou seja, manipulação do elemento tElement = template), portanto, manipulações que se aplicam a todos os clones DOM do modelo associado à diretiva. (Se você também precisar de uma função de vínculo (ou funções de pré e pós-vínculo) e tiver definido uma função de compilação, a função de compilação deverá retornar a (s) função (s) de vínculo porque o 'link'atributo será ignorado se o 'compile'atributo estiver definido.)

  • função de link - normalmente usada para registrar retornos de chamada do ouvinte (ou seja, $watchexpressões no escopo), bem como atualizar o DOM (ou seja, manipulação de iElement = elemento de instância individual). É executado após a clonagem do modelo. Por exemplo, dentro de um <li ng-repeat...>, a função de link é executada após o <li>modelo (tElement) ter sido clonado (em um iElement) para esse <li>elemento em particular . A $watchpermite que uma diretiva seja notificada de alterações na propriedade do escopo (um escopo está associado a cada instância), o que permite que a diretiva processe um valor atualizado da instância no DOM.

  • função do controlador - deve ser usada quando outra diretiva precisar interagir com esta diretiva. Por exemplo, na página inicial do AngularJS, a diretiva de painel precisa se adicionar ao escopo mantido pela diretiva de guias, portanto, a diretiva de guias precisa definir um método de controlador (think API) que a diretiva de painel pode acessar / chamar.

    Para uma explicação mais detalhada das diretivas de guias e painéis, e por que a diretiva de guias cria uma função em seu controlador usando this(em vez de $scope), consulte o escopo 'this' vs $ nos controladores AngularJS .

Em geral, você pode colocar métodos $watchesetc. na função de controle ou link da diretiva. O controlador será executado primeiro, o que às vezes é importante (consulte este violão que registra quando as funções ctrl e link são executadas com duas diretivas aninhadas). Como Josh mencionou em um comentário , você pode colocar funções de manipulação de escopo dentro de um controlador apenas para consistência com o restante da estrutura.

Mark Rajcok
fonte
131
Esta explicação deve estar nos principais documentos do AngularJS ou, pelo menos, uma referência a ela #
Dogoku
7
Esta é uma resposta informativa, mas acho que é difícil de ler. Talvez mais pontuação e frases menores possam ajudar. No geral, sou grato pela resposta.
Marty Cortez
O compilador $ ignora o atributo 'link' na presença de um atributo 'compile'. Mas e na presença de um atributo 'controller'? 'Controller' faz com que o compilador $ ignore um ou ambos os atributos 'link' e 'compile'? É possível e / ou aconselhável usar uma 'compilação' junto com um 'controlador'?
Carl G
11
@CarlG, a presença de um atributo do controlador não afeta o compilador $ no que diz respeito ao link e compilação. Você pode usar compilação e controlador.
precisa saber é o seguinte
11
"Ouvintes do DOM" NÃO são "(ou seja, expressões $ watch no escopo)". Um ouve o DOM para eventos como mouseovero outro, o escopo para alterações de propriedade. Grande diferença.
Dmitri Zaitsev
56

Como complemento à resposta de Mark, a função de compilação não tem acesso ao escopo, mas a função de link.

Eu realmente recomendo este vídeo; Diretrizes para redação de Misko Hevery (o pai do AngularJS), onde ele descreve diferenças e algumas técnicas. (Diferença entre a função de compilação e a função de link na marca 14:41 no vídeo ).

Pixic
fonte
3
+1 no link para o vídeo. É muito informativo.
precisa saber é o seguinte
2
jvandemo.com/…
EMuentes
35
  1. executando código antes da compilação: use controller
  2. código em execução após a compilação: use Link

Convenção angular: escreva a lógica de negócios no controlador e a manipulação do DOM no link.

Além disso, você pode chamar uma função de controlador da função de link de outra diretiva. Por exemplo, você tem 3 diretivas personalizadas

<animal>
<panther>
<leopard></leopard>
</panther> 
</animal>

e você deseja acessar o animal de dentro da diretiva "leopardo".

http://egghead.io/lessons/angularjs-directive-communication será útil para saber sobre a comunicação entre diretivas

Rahul
fonte
18
"executando código antes da compilação: use o controlador". Isso está incorreto; compilesempre será executado antes controller .
Izhaki 07/07
Você não (pelo menos não de maneira direta) seria capaz de acessar animais a partir de sua diretiva de leopardo. As diretivas filho podem acessar os métodos do controlador em uma diretiva pai, mas as diretivas irmãos (como no exemplo acima) não podem chamar os controladores uns dos outros.
Benjamin White
2
Os leopardos são realmente um tipo de pantera? Além disso, em uma nota lateral ... Você pode ter um link - e - um controlador em uma diretiva?
Cody
11
sim leopardo / onças são panteras. e sim, você tem link e controlador dentro da diretiva.
Rahul
11
No guia do desenvolvedor Angular: "Prática recomendada: use o controlador quando desejar expor uma API a outras diretivas. Caso contrário, use o link".
Martin van Driel
6

função de compilação -

  1. é chamado antes da função de controlador e link.
  2. Na função de compilação, você possui o DOM do modelo original para poder fazer alterações no DOM original antes que o AngularJS crie uma instância e antes que um escopo seja criado.
  3. ng-repeat é um exemplo perfeito - a sintaxe original é o elemento do modelo, os elementos repetidos no HTML são instâncias
  4. Pode haver várias instâncias de elemento e apenas um elemento de modelo
  5. O escopo ainda não está disponível
  6. Função de compilação pode retornar função e objeto
  7. retornando uma função (pós-link) - é equivalente a registrar a função de vinculação através da propriedade link do objeto de configuração quando a função de compilação está vazia.
  8. retornar um objeto com função (s) registrada (s) através das propriedades pré e pós - permite controlar quando uma função de vinculação deve ser chamada durante a fase de vinculação. Veja as informações sobre as funções de pré-link e pós-link abaixo.

sintaxe

function compile(tElement, tAttrs, transclude) { ... }

controlador

  1. chamado após a função de compilação
  2. escopo está disponível aqui
  3. pode ser acessado por outras diretivas (consulte o atributo exigem)

pré - link

  1. A função de link é responsável por registrar os ouvintes do DOM, bem como atualizar o DOM. É executado após a clonagem do modelo. É aqui que a maior parte da lógica da diretiva será colocada.

  2. Você pode atualizar o dom no controlador usando angular.element, mas isso não é recomendado, pois o elemento é fornecido na função de link

  3. A função de pré-link é usada para implementar lógica que é executada quando j angular já compilou os elementos filhos, mas antes que qualquer link posterior do elemento filho fosse chamado

pós-link

  1. diretiva que possui apenas a função de link, angular trata a função como um link de postagem

  2. O post será executado após as funções de compilação, controlador e pré-link, por isso é considerado o local mais seguro e padrão para adicionar sua lógica de diretiva

Sunil Garg
fonte