Alguém pode explicar em termos simples?
Os documentos parecem um pouco obtusos. Não estou obtendo a essência e o panorama geral de quando usar um sobre o outro. Um exemplo contrastando os dois seria incrível.
javascript
angularjs
numan salati
fonte
fonte
Respostas:
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.
função de link - use para registrar ouvintes DOM (por exemplo, expressões $ watch no escopo da instância), bem como manipulação DOM da instância ( por exemplo , 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 depois que o modelo <li> (tElement) foi clonado (em um iElement) para esse elemento <li> específico.
Um $ watch () permite que uma diretiva seja notificada de alterações na propriedade do escopo da instância (um escopo da instância está associado a cada instância), o que permite à diretiva renderizar um valor atualizado da instância para o DOM - copiando o conteúdo do escopo da instância para o DOM.
Observe que as transformações do DOM podem ser feitas na função de compilação e / ou na função de link.
A maioria das diretivas precisa apenas de uma função de link, uma vez que a maioria das diretivas lida apenas com uma instância específica do elemento DOM (e seu escopo de instância).
Uma maneira de ajudar a determinar qual usar: considere que a função de compilação não recebe um
scope
argumento. (Estou intencionalmente ignorando o argumento da função de vinculação de transclude, que recebe um escopo transcluído - isso raramente é usado.) Portanto, a função de compilação não pode fazer o que você deseja que exija um escopo (instância) - você pode Não observe nenhuma propriedade de escopo de modelo / instância, você não pode manipular o DOM usando informações de escopo de instância, não pode chamar funções definidas no escopo de instância, etc.No entanto, a função de compilação (como a função de link) tem acesso aos atributos. Portanto, se suas manipulações DOM não exigirem o escopo da instância, você poderá usar uma função de compilação. Aqui está um exemplo de diretiva que usa apenas uma função de compilação, por esses motivos. Ele examina os atributos, mas não precisa de um escopo de instância para fazer seu trabalho.
Aqui está um exemplo de diretiva que também usa apenas uma função de compilação. A diretiva precisa apenas transformar o DOM do modelo, para que uma função de compilação possa ser usada.
Outra maneira de ajudar a determinar qual usar: se você não usar o parâmetro "elemento" na função de link, provavelmente não precisará de uma função de link.
Como a maioria das diretivas possui uma função de link, não fornecerei exemplos - elas devem ser muito fáceis de encontrar.
Observe que se você precisar de uma função de compilação e de uma função de link (ou funções de pré e pós-link), a função de compilação deverá retornar as funções de link porque o atributo 'link' será ignorado se o atributo 'compile' estiver definido.
Veja também
fonte
if you don't use the "element" parameter in the link function, then you probably don't need a link function.
que quer dizer "escopo" em vez de "elemento"?Eu bati minha cabeça contra a parede por alguns dias, e eu sinto que um pouco mais de explicação está em ordem.
Basicamente, os documentos mencionam que a separação é amplamente um aprimoramento de desempenho. Eu reiteraria que a fase de compilação é usada principalmente quando você precisa modificar o DOM ANTES de os subelementos serem compilados.
Para nossos propósitos, vou enfatizar a terminologia, que é confusa:
O compilador SERVICE ($ compile) é o mecanismo angular que processa o DOM e executa os vários bits de código nas diretivas.
A função de compilação é um bit de código dentro de uma diretiva, que é executada em um determinado momento pelo compilador SERVICE ($ compile).
Algumas notas sobre a função de compilação:
Você não pode modificar o elemento ROOT (aquele afetado pela sua diretiva), pois ele já está sendo compilado a partir do nível externo do DOM (o SERVICE de compilação já examinou as diretivas nesse elemento).
Se você deseja adicionar outras diretivas aos elementos (aninhados), você pode:
Tem que adicioná-los durante a fase de compilação.
É necessário injetar o serviço de compilação na fase de vinculação e compilar os elementos manualmente. MAS, cuidado com a compilação de algo duas vezes!
Também é útil ver como o aninhamento e as chamadas explícitas para $ compilam, então criei um playground para ver isso em http://jsbin.com/imUPAMoV/1/edit . Basicamente, ele apenas registra as etapas no console.log.
Vou indicar os resultados do que você veria nessa lixeira aqui. Para um DOM de diretivas personalizadas tp e sp aninhadas da seguinte maneira:
O serviço de compilação angular chamará:
O código jsbin também possui a função de pós-link tp chamada explicitamente o SERVICE de compilação em uma terceira diretiva (up), que executa todas as três etapas no final.
Agora, quero percorrer alguns cenários para mostrar como alguém pode usar o link de compilação e fazer várias coisas:
CENÁRIO 1: Diretiva como MACRO
Você deseja adicionar uma diretiva (digamos, ng-show) dinamicamente a algo em seu modelo que possa derivar de um atributo.
Digamos que você tenha um templateUrl que aponte para:
e você deseja uma diretiva personalizada:
que transforma o DOM nisso:
basicamente, você deseja reduzir o padrão com alguma estrutura de modelo consistente que sua diretiva possa interpretar. Em outras palavras: você quer uma macro.
Esse é um ótimo uso para a fase de compilação, pois você pode basear todas as manipulações do DOM em coisas que você conhece apenas pelos atributos. Basta usar o jQuery para adicionar os atributos:
A sequência de operações será (você pode ver isso através do jsbin mencionado anteriormente):
No exemplo acima, nenhuma ligação é necessária, pois todo o trabalho da diretiva foi realizado na compilação FUNCTION.
A qualquer momento, o código em uma diretiva pode solicitar que o compilador SERVICE seja executado em elementos adicionais.
Isso significa que podemos fazer exatamente a mesma coisa em uma função de link se você injetar o serviço de compilação:
Se você tem certeza de que os elementos que você está passando para o $ compile SERVICE originalmente eram livres de diretiva (por exemplo, eles vieram de um modelo que você definiu ou apenas os criaram com angular.element ()), o resultado final é praticamente o mesmo de antes (embora você possa estar repetindo algum trabalho). No entanto, se o elemento continha outras diretrizes, você apenas as processou novamente, o que pode causar todo tipo de comportamento irregular (por exemplo, registro duplo de eventos e relógios).
Assim, a fase de compilação é uma opção muito melhor para o trabalho no estilo macro.
CENÁRIO 2: Configuração do DOM via dados do escopo
Este segue o exemplo acima. Suponha que você precise acessar o escopo enquanto manipula o DOM. Bem, nesse caso, a seção de compilação é inútil para você, pois ocorre antes que um escopo esteja disponível.
Então, digamos que você queira exibir uma entrada com validações, mas deseja exportar suas validações de uma classe ORM do lado do servidor (DRY) e aplicá-las automaticamente e gerar a interface do usuário do lado do cliente adequada para essas validações.
Seu modelo pode pressionar:
e você pode querer uma diretiva:
para incluir automaticamente as diretivas e divs apropriadas para mostrar os vários erros de validação:
Nesse caso, você definitivamente precisa acessar o escopo (já que é onde suas validações são armazenadas) e terá que compilar as adições manualmente, novamente tomando cuidado para não compilar as coisas duas vezes. (como uma observação lateral, você precisaria definir um nome na tag de formulário que contém (estou assumindo o formulário aqui) e poderia acessá-lo em link com iElement.parent (). controller ('form'). $ name) .
Nesse caso, não faz sentido escrever uma função de compilação. Link é realmente o que você deseja. Os passos seriam:
Igual a:
Obviamente, você pode compilar os elementos aninhados um a um para evitar a preocupação com o processamento duplicado das diretivas ng ao compilar o elemento de nível superior novamente.
Uma observação final sobre esse cenário: sugeri que você estaria pressionando a definição das validações de um servidor e, no meu exemplo, mostrei-as como dados já no escopo. Deixo como um exercício para o leitor descobrir como é possível lidar com a necessidade de extrair esses dados de uma API REST (dica: compilação adiada).
CENÁRIO 3: ligação de dados bidirecional via link
Obviamente, o uso mais comum do link é simplesmente conectar a ligação de dados bidirecional via watch / apply. A maioria das diretivas se enquadra nessa categoria, portanto é abordada adequadamente em outros lugares.
fonte
Dos documentos:
Portanto, pelo menos em alguns casos, as duas fases existem separadamente como uma otimização.
From @ UmurKontacı :
fonte
DOM
a transformação, deve sercompile
se você quiser adicionar algumas características são as mudanças de comportamento, ele deve estar emlink
.Isto é da palestra de Misko sobre diretivas. http://youtu.be/WqmeI5fZcho?t=16m23s
fonte
Um pouco tarde para a discussão. Mas, para o benefício de futuros leitores:
Me deparei com o vídeo a seguir, que explica Compile e Link no Angular JS de uma maneira muito boa:
https://www.youtube.com/watch?v=bjFqSyddCeA
Não seria agradável copiar / digitar todo o conteúdo aqui. Tirei algumas capturas de tela do vídeo, que explicam todas as etapas das fases de Compilação e Link:
A segunda captura de tela é um pouco confusa. Mas, se seguirmos a numeração dos passos, é bastante simples.
Primeiro ciclo: "Compilar" é executado em todas as diretivas primeiro.
Segundo ciclo: "Controlador" e "Pré-Link" são executados (apenas um após o outro) Terceiro ciclo: "Pós-Link" é executado em ordem inversa (a partir do interior)
A seguir está o código, que demonstra o acima:
ATUALIZAR:
A parte 2 do mesmo vídeo está disponível aqui: https://www.youtube.com/watch?v=1M3LZ1cu7rw O vídeo explica mais sobre como modificar o DOM e manipular eventos durante o processo de Compilação e Link do Angular JS, em um exemplo simples .
fonte
compile
epost
para modificar um DOM antes que ele seja modificado emtemplate
parte a partir de uma diretiva de fornecedor.Duas fases: compilar e vincular
Compilar:
Percorra a árvore do DOM procurando diretivas (elementos / atributos / classes / comentários). Cada compilação de uma diretiva pode modificar seu modelo ou seu conteúdo que ainda não foi compilado. Quando uma diretiva é correspondida, ela retorna uma função de vinculação, que é usada em uma fase posterior para vincular elementos. No final da fase de compilação, temos uma lista de diretivas compiladas e suas funções de vinculação correspondentes.
Ligação:
Quando um elemento é vinculado, a árvore DOM é interrompida em seu ponto de ramificação na árvore DOM e o conteúdo é substituído pela instância compilada (e vinculada) do modelo. O conteúdo deslocado original é descartado ou, no caso de transclusão, vinculado novamente ao modelo. Com a transclusão, as duas peças são ligadas novamente (como uma corrente, com a peça do modelo no meio). Quando a função de link é chamada, o modelo já foi vinculado a um escopo e adicionado como filho do elemento. A função de link é sua oportunidade de manipular ainda mais o DOM e configurar ouvintes de alterações.
fonte
Esta questão é antiga por gostaria de fazer um breve resumo que pode ajudar:
fonte