Ao escrever uma diretiva Angular, é possível usar qualquer uma das seguintes funções para manipular o comportamento do DOM, o conteúdo e a aparência do elemento no qual a diretiva é declarada:
- compilar
- controlador
- pré-link
- pós-link
Parece haver alguma confusão sobre qual função deve ser usada. Esta pergunta abrange:
Princípios básicos da diretiva
- Como declarar as várias funções?
- Qual é a diferença entre um modelo de origem e um modelo de instância ?
- Em que ordem as funções de diretiva são executadas?
- O que mais acontece entre essas chamadas de função?
Natureza da função, faça e não faça
Perguntas relacionadas:
- Diretiva: link vs compilar vs controlador .
- Diferença entre as funções 'controller', 'link' e 'compile' ao definir uma diretiva angular.js .
- Qual é a diferença entre a função de compilação e link em angularjs .
- Diferença entre o elemento pré-compilação e pós-compilação nas diretivas AngularJS? .
- Diretiva JS angular - modelo, compilação ou link? .
- post link vs pre link nas diretivas js angulares .
angularjs
angularjs-directive
Izhaki
fonte
fonte
Respostas:
Em que ordem as funções de diretiva são executadas?
Para uma única diretiva
Com base na seguinte plunk , considere a seguinte marcação HTML:
Com a seguinte declaração de diretiva:
A saída do console será:
Podemos ver que
compile
é executado primeiro, depoiscontroller
, depoispre-link
e últimopost-link
.Para diretivas aninhadas
A marcação HTML original geralmente é feita de elementos aninhados, cada um com sua própria diretiva. Como na seguinte marcação (veja plunk ):
A saída do console ficará assim:
Podemos distinguir duas fases aqui - a fase de compilação e a fase de link .
A fase de compilação
Quando o DOM é carregado, o Angular inicia a fase de compilação, onde percorre a marcação de cima para baixo e chama
compile
todas as diretivas. Graficamente, poderíamos expressá-lo assim:Talvez seja importante mencionar que, nesse estágio, os modelos que a função de compilação obtém são os modelos de origem (não o modelo de instância).
A fase do link
As instâncias do DOM geralmente são simplesmente o resultado de um modelo de origem sendo renderizado no DOM, mas podem ser criados
ng-repeat
ou introduzidos em tempo real.Sempre que uma nova instância de um elemento com uma diretiva é renderizada no DOM, a fase do link é iniciada.
Nesta fase, Angular chama
controller
,pre-link
itera filhos e chamapost-link
todas as diretivas, como:fonte
O que mais acontece entre essas chamadas de função?
As várias funções directiva são executados a partir de dentro de duas outras funções angulares chamados
$compile
(onde a directiva dacompile
for executado) e uma função de chamada internonodeLinkFn
(onde o da directivacontroller
,preLink
epostLink
são executadas). Várias coisas acontecem dentro da função angular antes e depois das funções diretivas serem chamadas. Talvez o mais notável seja a recursão infantil. A ilustração simplificada a seguir mostra as principais etapas nas fases de compilação e link:Para demonstrar essas etapas, vamos usar a seguinte marcação HTML:
Com a seguinte diretiva:
Compilar
A
compile
API tem a seguinte aparência:Geralmente, os parâmetros são prefixados com
t
para significar que os elementos e atributos fornecidos são os do modelo de origem, e não os da instância.Antes da chamada para o
compile
conteúdo transcluído (se houver), é removido e o modelo é aplicado à marcação. Assim, o elemento fornecido para acompile
função terá a seguinte aparência:Observe que o conteúdo transcluído não é reinserido neste momento.
Após a chamada para a diretiva de
.compile
, o Angular percorrerá todos os elementos filhos, incluindo aqueles que podem ter sido introduzidos pela diretiva (os elementos do modelo, por exemplo).Criação de Instância
No nosso caso, três instâncias do modelo de origem acima serão criadas (por
ng-repeat
). Portanto, a sequência a seguir será executada três vezes, uma vez por instância.Controlador
A
controller
API envolve:Entrando na fase de link, a função de link retornada via
$compile
agora é fornecida com um escopo.Primeiro, a função de link cria um escopo filho (
scope: true
) ou um escopo isolado (scope: {...}
), se solicitado.O controlador é então executado, fornecido com o escopo do elemento de instância.
Pré-link
A
pre-link
API tem a seguinte aparência:Praticamente nada acontece entre a chamada para a diretiva
.controller
e a.preLink
função. A Angular ainda fornece recomendações sobre como cada uma deve ser usada.Seguindo o
.preLink
chamada, a função de link percorrerá cada elemento filho - chamando a função de link correta e anexando a ele o escopo atual (que serve como o escopo pai dos elementos filhos).Post-link
A
post-link
API é semelhante à dapre-link
função:Talvez valha a pena notar que, uma vez
.postLink
chamada a função de uma diretiva , o processo de vinculação de todos os seus elementos filhos foi concluído, incluindo todas as.postLink
funções das crianças .Isso significa que, quando o tempo
.postLink
é chamado, as crianças estão 'vivas' e estão prontas. Isso inclui:O modelo nesse estágio ficará assim:
fonte
Como declarar as várias funções?
Compilar, Controlador, Pré-link e Pós-link
Se alguém usar todas as quatro funções, a diretiva seguirá este formato:
Observe que a compilação retorna um objeto que contém as funções de pré-link e pós-link; no jargão angular, dizemos que a função de compilação retorna uma função de modelo .
Compilar, Controlar e Pós-Link
Se
pre-link
não for necessário, a função de compilação pode simplesmente retornar a função de pós-link em vez de um objeto de definição, assim:Às vezes, deseja-se adicionar um
compile
método, após alink
definição do método (post) . Para isso, pode-se usar:Controlador e pós-link
Se nenhuma função de compilação for necessária, é possível pular completamente sua declaração e fornecer a função pós-link sob a
link
propriedade do objeto de configuração da diretiva:Sem controlador
Em qualquer um dos exemplos acima, pode-se simplesmente remover a
controller
função, se não for necessário. Por exemplo, se apenas umapost-link
função é necessária, pode-se usar:fonte
Qual é a diferença entre um modelo de origem e um modelo de instância ?
O fato de Angular permitir a manipulação de DOM significa que a marcação de entrada no processo de compilação às vezes difere da saída. Particularmente, algumas marcações de entrada podem ser clonadas algumas vezes (como com
ng-repeat
) antes de serem renderizadas no DOM.A terminologia angular é um pouco inconsistente, mas ainda distingue entre dois tipos de marcações:
A seguinte marcação demonstra isso:
O html de origem define
que serve como modelo de origem.
Mas, como está dentro de uma
ng-repeat
diretiva, esse modelo de origem será clonado (3 vezes no nosso caso). Esses clones são modelo de instância, cada um aparecerá no DOM e será vinculado ao escopo relevante.fonte
Função de compilação
Cada diretiva
compile
função de é chamada apenas uma vez, quando o Angular é iniciado.Oficialmente, este é o local para executar manipulações de modelo (de origem) que não envolvem escopo ou ligação de dados.
Principalmente, isso é feito para fins de otimização; considere a seguinte marcação:
A
<my-raw>
diretiva renderizará um conjunto específico de marcação DOM. Para que possamos:ng-repeat
duplicar o modelo de origem (<my-raw>
) e modifique a marcação de cada modelo de instância (fora dacompile
função).compile
função) e permitang-repeat
duplicá-la.Se houver 1000 itens na
raws
coleção, a última opção poderá ser mais rápida que a anterior.Faz:
Não
fonte
Função de controlador
A
controller
função de cada diretiva é chamada sempre que um novo elemento relacionado é instanciado.Oficialmente, a
controller
função é onde:Novamente, é importante lembrar que, se a diretiva envolver um escopo isolado, quaisquer propriedades nela herdadas do escopo pai ainda não estarão disponíveis.
Faz:
Não:
fonte
Função pós-link
Quando a
post-link
função é chamada, todas as etapas anteriores ocorreram - encadernação, transclusão etc.Normalmente, este é um local para manipular ainda mais o DOM renderizado.
Faz:
fonte
Função pré-link
A
pre-link
função de cada diretiva é chamada sempre que um novo elemento relacionado é instanciado.Como visto anteriormente na seção de ordem de compilação, as
pre-link
funções são chamadas pai-e-filho, enquanto aspost-link
funções são chamadaschild-then-parent
.A
pre-link
função raramente é usada, mas pode ser útil em cenários especiais; por exemplo, quando um controlador filho se registra no controlador pai, mas o registro deve ser de umaparent-then-child
maneira (ngModelController
faz as coisas dessa maneira).Não:
fonte