A diretiva é uma maneira de ensinar HTML a fazer alguns novos truques. Durante a compilação DOM, as diretrizes correspondem a HTML e executam. Isso permite o comportamento de registro de diretiva ou a conversão de estruturas DOM.
A Angular vem com um conjunto de diretivas internas, o que é muito útil para a criação de um aplicativo da web. Se você continuar a se expandir, poderá definir o idioma específico do domínio (DSL) no HTML.
1. Diretivas de cotação em HTML
A diretiva possui nomeação de estilo de camelo, como o ngbind (parece ser inutilizável nas propriedades ~). No entanto, a diretiva também pode ser nomeada com um tipo de fundo de cobra (capa de cobra), que precisa ser conectado através de: (cólon), - (menos) ou _ (sublinhado). Como opção opcional, a diretiva pode ser prefixada com "X-" ou "Data-" para atender às necessidades de verificação HTML. Aqui estão os nomes legais das diretrizes:
A diretiva pode ser colocada em nomes de elementos, atributos, classes e comentários. A seguir, é a maneira equivalente de citar Mydir, a diretiva. (Mas muitas diretivas são limitadas ao uso de "propriedades")
<span my-dir = "exp"> </span> <pan> </span> <my-dir> </ meu-dir> <!-Diretiva: my-Dir exp->
A diretiva pode ser citada de várias maneiras, e as seguintes listas N maneiras equivalentes:
<! Doctype html> <html lang = "zh-cn" ng-app> <head> <meta charset = "utf-8"> <title> Invoke-Direction </ititle> <style type = "text/css"> .ng-cloak {display: nenhum; } </style> </ad Head> <body> <div ng --Controller = "myctrl"> hello <input ng-model = "name"/> <hr/> ngbind = "name" Isso não pode ser usado ~~ <span ngbind = "name"> </span> <br/> ng: bind = "name" ng_bind = "name" <span ng_bind = "name"> </span> <br/> ng-bind = "name" <span ng-bind = "name"> </span> <br/> data-ng-bind = "name" <span data-ng-bind = "name"> </span> <br/bind = x-bind = "Nome" " x-ng-bind = "name"> </span> <br/> </div> <script src = "../ angular-1.0.1.js" type = "text/javascript"> </script> <script type = "text/javascript"> function myctrl ($ scope) {scope.name = "beleza"; } </script> </body> </html>2. Interpolação de cordas
Durante o processo de compilação, o compilador corresponde ao texto com expressões incorporadas em atributos (como {{algo}}) através do serviço $ interpolate. Essas expressões serão registradas como relógios e serão atualizadas juntas como parte do ciclo de digestão (não era um loop de digestão antes?!). Aqui está uma interpolação simples:
<img src = "img/{{nome de usuário}}. jpg"/> hello {{userrame}}!
3. Processo de compilação e correspondência de diretiva
Três etapas para "compilar" HTML:
1. Primeiro, converta HTML em objetos DOM através da API padrão do navegador. Este é um passo muito importante. Porque o modelo deve ser parsável (compatível com as especificações). Isso pode ser comparado com a maioria dos sistemas de modelos, que geralmente são baseados em strings, não em elementos DOM.
2. A compilação do DOM é feita chamando o método $ comply (). Este método atravessa o DOM e corresponde à diretiva. Se a correspondência for bem -sucedida, ela será adicionada à lista de diretivas juntamente com o DOM correspondente. Enquanto todas as diretrizes associadas ao DOM especificado forem identificadas, elas serão classificadas em prioridade e executarão sua função compilation () nessa ordem. A função de compilação da diretiva tem a oportunidade de modificar a estrutura DOM e é responsável por gerar a análise da função Link (). O método $ compile () retorna uma função de vinculação combinada, que é uma coleção de funções vinculadas retornadas pela função de compilação da própria diretiva.
3. Conecte o modelo ao escopo através da função de vinculação retornada na etapa anterior. Por sua vez, isso chama a função de vinculação da Diretiva, permitindo que eles registrem alguns ouvintes no elemento e crie alguns relógios com escopo. O resultado disso é uma ligação bidirecional e instantânea entre o escopo e o DOM. Quando o escopo mudar, o DOM receberá a resposta correspondente.
var $ compile = ...; // injetado no seu código var scope = ...; var html = '<div ng-bind =' exp '> </div>'; // Etapa 1: analisar html no elemento dom var modelo = angular.Element (html); // Etapa 2: Compile o modelo var linkfn = $ compile (modelo); // Etapa 3: vincule o modelo compilado com o escopo. linkfn (escopo);
4. Razões por trás da separação de compilação/link
Neste momento, você pode se perguntar por que o processo de compilação é dividido em duas etapas: compilar e vincular. Para entender isso, vamos dar uma olhada em um exemplo real (repetidor)
Olá {{user}}, você tem estas ações: <ul> <li ng-repeat = "Action in user.actions"> {{action.description}} </li> </ul>Simplificando, a razão pela qual separamos as duas etapas de compilação e link é que, às vezes, a estrutura DOM correspondente precisa ser alterada após a mudança do modelo, como repetidores.
Quando o exemplo acima é compilado, o compilador iterará em todos os nós para encontrar a diretiva. {{user}} é um exemplo de uma diretiva de interpolação. NGREPEAT é outra diretiva. Mas o NGREPEAT tem uma dificuldade. Requer a capacidade de criar rapidamente um novo LI para todas as ações nos usuários. Isso significa que, para satisfazer o objetivo de clonar Li e incorporar ações específicas (aqui se refere a um dos valores das ações do usuário), ele precisa manter uma cópia limpa do elemento LI, que precisa ser clonado e inserido no elemento UL. Mas clonar o elemento LI não é suficiente. Li também precisa ser compilado para que sua diretiva ({{Action.Descriptions}}) possa ser analisada no escopo correto. O método original geralmente simplesmente insere uma cópia do elemento LI e o compila. No entanto, a compilação de cópias de cada elemento Li será mais lenta, porque o processo de compilação exige que atravessemos a árvore do nó DOM, encontre diretivas e execute -as. Se tivermos uma compilação que precisa processar 100 itens através do repetidor, ficaremos presos a problemas de desempenho.
A solução para o problema é dividir o processo de compilação em duas etapas. O estágio de compilação reconhece todas as diretrizes e as classifica por prioridade, vinculando um escopo específico a um LI específico durante o estágio de ligação.
O NGREPEAT compila LIS individual separadamente para impedir que o processo de compilação caia nos elementos LI. O resultado da compilação do elemento LI é uma função de vinculação da diretiva que contém todas as diretivas contidas no elemento LI, pronto para se conectar com a cópia do elemento Li específico. Em tempo de execução, o NGREPEAT monitora a expressão e é adicionado como um item a uma matriz de cópias de elementos de LI, criando um novo escopo para os elementos Li clonados e chamando a função de link correspondente à cópia.
Resumir:
1. As funções de compilação de função compilar são relativamente raras nas diretrizes, porque a maioria das diretivas se preocupa apenas em trabalhar com elementos DOM especificados, em vez de alterar os modelos dos elementos DOM (o próprio DOM e sua estrutura interna). Para otimizar o desempenho, algumas operações que podem ser compartilhadas por instâncias de diretiva podem ser movidas para a função de compilação.
2. Função do link - Muito poucas diretivas não têm função de link. A função de link permite que a diretiva registre um ouvinte na cópia especificada da instância do elemento DOM ou copie conteúdo específico do escopo para o DOM.
5. Escreva uma diretiva (versão simples)
Neste exemplo, criaremos uma diretiva que exibe o horário atual de acordo com o formato de entrada.
<! Doctype html> <html lang = "zh-cn" ng-app = "timeFormat"> <head> <meta charset = "utf-8"> <title> time-format </title> </ad Head> <body> <div ng --Contoller = "myctrl" id = "main> main> format: format: <body> <div ng-controller =" Myctrl "id =" main> format "format: type = "text"/> <hr/> <!-O seguinte atributo X-Current-Time é tentar a nomeação legal mencionada acima ~~ Current: tempo, tempo atual, current_time, tempo-corrente -__- !!! -> O horário atual é: <span x-current time = "format" id = "myFormat"> </span> <br/> <botão ng-click = "remover ()"> remover o span </button> </div> <script src = "../ angular-1.0.1.js" type = "text/javasscript"> </script> </script> </script> </script> type = "text/javascript"> angular.module ("timeformat", []) // Registre o método de fábrica de diretiva de "CurrentTime" no aplicativo TimeFormat // Como mencionado acima, a injeção de dependência pode ser escrita diretamente nos parâmetros de função, que não é necessário. Adicione uma função de compilação, por que? Executa o escopo. }). Controller ("myctrl", função ($ scope, $ rootscope) {$ scope.format = "m/d/yy h: mm: ss a"; $ scope.reMove = function () {var oforty) O Evento de Destruir pode ser acionado!6. Escreva uma diretiva (versão detalhada)
Abaixo está uma criação de amostra de uma diretiva (modelo de definição de objeto de diretiva). Se você quiser ver a lista detalhada, continue lendo.
var myModule = angular.module (...); mymodule.Directive ('DirectiveName', Função Factory (injetável) {var diretivoefinitionObject = {Prioridade: 0, modelo: '<div> </div>', modelurl: 'Directive.html', substituir: FALSO, FUNCLUDE: FALSE, FALSE: 'A', escopo: false, False, Function: Funct): Funda: Funda: Funda: 'A' A 'A', Escopo: False, Prelink (escopo, iElement, IATTRS, controlador) {...}, post: função pós -link (escopo, iElement, IATTRS, controlador) {...}}}, link: função pós -regresso (escopo, iElement, iattrs) {...}};Na maioria dos cenários, não precisamos de controle preciso, para que a definição acima possa ser simplificada. Definir cada parte do modelo será explicado no capítulo seguinte. Neste capítulo, nos concentramos apenas nos isômeros desse esqueleto que definem o modelo (isômeros desse esqueleto, não entendo ... ansioso pela adição de todos).
A primeira etapa para simplificar seu código é confiar nos valores padrão. Portanto, o código acima pode ser simplificado para:
var myModule = angular.module (...); myModule.Directive ('Directivename', Função Factory (injetáveis) {var diretivoefinitionObject = {compile: function Compile (televisão, tattrs) {retorna função post -link (escopo, iElement, iattrs) {...}}}}; retorno diretorEfinitionObject;});A maioria das diretivas se preocupa apenas com instâncias, não a conversão de modelos, para que possam ser simplificadas (traduzidas com muita força ... ansioso pela adição de todos):
var myModule = angular.module (...); myModule.Directive ('DirectiveName', Função Factory (injetáveis) {Return Function PostLink (SCOPE, IELEMENT, IATTRS) {...}});7. Método da fábrica
O método da fábrica é responsável pela criação de diretrizes. É usado apenas uma vez, exatamente quando o compilador corresponde primeiro à diretiva. Você pode fazer algumas operações de inicialização aqui. O método da fábrica é executado através do $ injetor.invoke, permitindo que ele cumpra todas as regras da declaração de injeção (anotação de regras de injeção), tornando -o injetável.
8. Descrição do objeto de definição de diretiva
Os objetos de definição da diretiva fornecem a estrutura do compilador. As propriedades são as seguintes:
1.Nome - o nome do escopo atual. O valor padrão pode ser usado ao se registrar (não preenchido).
2.Prioridade- Quando existem várias diretivas definidas no mesmo elemento DOM, às vezes é necessário esclarecer sua ordem de execução. Esta propriedade é usada para classificar antes da chamada de função de compilação da diretiva. Se a prioridade for a mesma, a ordem de execução é incerta (após experimentos preliminares, aqueles com maior prioridade são executados primeiro e o mesmo nível é semelhante à "execução pós-ligação" primeiro ".
3.Merminal (último grupo) - Se definido como "True", significa que a prioridade atual se tornará a diretiva do último grupo de execução. Se qualquer diretiva for a mesma que a prioridade atual, eles ainda serão executados, mas a ordem é incerta (embora a ordem seja incerta, é basicamente a mesma que a ordem de prioridade. Após a execução da prioridade atual, a prioridade mais baixa não será executada novamente).
4.Scope - se definido como:
1) .TRUE - Um novo escopo será criado para esta diretiva. Se houver várias diretivas no mesmo elemento que exigirem um novo escopo, ele ainda criará apenas um escopo. As novas regras do escopo não se aplicam ao modelo raiz; portanto, o modelo raiz tende a obter um novo escopo.
2). {} (Hash de objeto) - Um novo escopo isolado será criado. A diferença entre o escopo "isolado" e o escopo geral é que ele não é herdado do escopo dos pais através de protótipos. Isso é muito útil para criar componentes reutilizáveis e pode efetivamente impedir a leitura ou modificação de dados do escopo dos pais. Esse escopo independente cria um hash de objeto com um conjunto de propriedades de escopo local derivadas do escopo dos pais. Essas propriedades locais são úteis para valores de alias para modelos -_-!. Definição local é um hash de propriedade de escopo local para sua fonte#&) $ &@#) ($ &@#_):
3). @ Ou @attr - Crie uma propriedade de escopo local para a propriedade DOM. Como o valor da propriedade é sempre o tipo de string, esse valor sempre retorna uma string. Se o nome do atributo não for especificado via @ATTR, o nome local sempre será com o nome do atributo DOM. Por exemplo, <widget my-attr = "hello {{name}}">, o escopo do widget é definido como: {localName: '@myattr'}. Em seguida, o nome local da propriedade Scope Widget mapeará o valor real convertido por "Hello {{Name}}". Após a mudança do valor do atributo, o atributo LocalName do escopo do widget também mudará de acordo (apenas uma via, diferente do "=" abaixo). O atributo de nome é lido no escopo dos pais (não o escopo do componente)
4). = OR = Expressão (talvez attr aqui) - Defina uma ligação bidirecional entre o atributo local do escopo e o atributo do escopo dos pais. Se o nome do Attt não for especificado, o nome local será consistente com o nome do atributo. Por exemplo, <widget my-attr = "parentModel">, o escopo definido pelo widget é: {localModel: '= myattr'}, então a propriedade do escopo do widget "LocalName" mapeará o "Modelel ParentModel" do escopo dos pais. Se ocorrer alguma alteração no ParentModel, o LocalModel também mudará e vice -versa. (Ligação bi-way)
5). & OR & Att - fornece uma maneira de executar uma expressão no contexto do escopo dos pais. Se o nome do Attt não for especificado, o nome local será consistente com o nome do atributo. Por exemplo, <widget my-attr = ”count = count + value”>, o escopo do widget é definido como: {localfn: 'increment ()'}, isolar a propriedade do escopo "localFN" apontará para uma função envolvida com uma expressão increment (). De um modo geral, queremos passar dados do escopo isolado para o escopo dos pais através de uma expressão. Isso pode ser feito passando um mapa do valor da chave de uma variável local na função de invólucro da expressão. Por exemplo, se a expressão for incremento (quantidade), podemos chamar LocalFN através do localFN ({valor: 22}) para especificar o valor do valor (o exemplo acima realmente não entende, e onde você foi?).
5. Construtor do Controlador. O controlador inicializará antes da etapa de pré-reticulação e permitirá que outras diretivas compartilhem através do necessário com o nome especificado (consulte a propriedade requisitiva abaixo). Isso permitirá que as diretrizes se comuniquem e aprimorem o comportamento mútuo. O controlador injeta os seguintes objetos locais por padrão:
1). $ Escopo - escopo combinado com o elemento atual
2). $ Elemento - elemento atual
3). $ Attrs - o objeto de atributo do elemento atual
4). $ Transclude - uma função de vinculação de transposição pré -ligada ao escopo de transposição atual: função (clonelinkingfn). (Uma função de vinculação transclude pré-ligada ao escopo de tradução correto)
6.Require - Solicite outro controlador para transmiti -lo para a atual função de vinculação da diretiva. exigir que o nome de um controlador direto seja passado. Se o controlador correspondente a esse nome não puder ser encontrado, um erro será lançado. O nome pode ser prefixado com o seguinte:
1).? - Não jogue exceções. Isso torna essa dependência uma opção.
2).^ - Um controlador que permite procurar elementos dos pais
7.Restrit - Uma sequência de um subconjunto de EACM, que limita a diretiva ao método de declaração especificado. Se omitido, a diretiva permitirá apenas declarações por meio de atributos:
1) E-Nome do elemento: <My-Direction> </ meu-Directive>
2) .a - Nome do atributo: <div my -Direction = "exp"> </div>
3). C - Nome da classe: <div class = "My -Directive: exp;"> </div>
4) .m-Comentário: <!-Diretiva: My-Directive Exp->
8.Template - Se substituir for verdadeiro, substitua o conteúdo do modelo pelo elemento HTML atual e migre as propriedades e a classe do elemento original juntos; Se falso, o elemento de modelo é tratado como um elemento filho do elemento atual. Para mais informações, consulte o capítulo "Criando widgets" (onde ... criando componentes está disponível ...)
9.Templateurl - é basicamente o mesmo que o modelo, mas o modelo é carregado através do URL especificado. Como o carregamento do modelo é assíncrono, a compilação e a vinculação serão pausadas e serão executadas após o carregamento.
10.ReguPLEA - Se definido como true, o modelo substituirá o elemento atual em vez de ser adicionado ao elemento atual como um elemento filho. (Nota: quando verdadeiro, o modelo deve ter um nó raiz)
11.Transclude - Compile o conteúdo de um elemento para que ele possa ser usado pela diretiva. Necessário (no modelo) a ser usado (referenciado). A vantagem da transclusão é que a função de vinculação pode obter uma função de tradução pré-ligada ao escopo atual. Geralmente, crie um widget e crie um escopo isolado. A tradução não é criança, mas um irmão do escopo isolado. Isso fará com que o widget tenha um estado privado e a transclusão estará vinculada ao escopo dos pais (pré-isolado). (Eu não entendo o parágrafo acima. Mas em experimentos reais, se o myDirective é chamado através de <qualquer minha-diretiva> {{name}}} </qualquer minha-diretiva> e o transclude é definido como true ou uma string e o modelo se retende. será um período extra em algum momento.
1) .TRUE - Converta o conteúdo desta diretiva. (Nesse sentido, é compilar diretamente o conteúdo e movê -lo para o local designado)
2). 'Elemento' - converte todo o elemento, incluindo outras diretrizes com menor prioridade. (Por exemplo, depois de compilar todo o conteúdo, ele é tratado como um todo (embrulhado P do lado de fora) e inserido no local especificado)
12.compile - Aqui está a função de compilação, que será explicada em detalhes nos capítulos seguintes
13.link - Aqui está a função de link, que será explicada em detalhes no capítulo seguinte. Esta propriedade é usada apenas se a propriedade Compile não estiver definida.
9. Função de compilação
Função Compile (Telement, TatTrs, Transclude) {…}
A função de compilação é usada para lidar com a conversão dos modelos DOM. Como a maioria das diretivas não requer modelos de conversão, a compilação não será usada com frequência. Diretiva que requer a função de compilação, geralmente aqueles que precisam converter modelos DOM (como NGREPEAT) ou aqueles que precisam carregar conteúdo de forma assíncrona (como NGView). A função de compilação possui os seguintes parâmetros:
1.Telement - O elemento do modelo usa o elemento diretivo atual. É seguro fazer apenas conversão de modelo no elemento atual ou no elemento atual do elemento.
2.TATTRS - Atributos de modelo - Atributos padronizados, declarados no elemento atual, podem ser compartilhados entre várias diretrizes. Para detalhes, consulte o capítulo dos atributos
3.Transclude uma função de vinculação para conversão: função (escopo, clonelinking).
Nota: Se o modelo foi clonado, a instância do modelo e a instância do link não podem ser o mesmo objeto. Para fazer isso, não é seguro fazer nada além de conversão DOM na função de compilação, que será aplicada a todos os clones. Em particular, a operação de registro do ouvinte do evento DOM deve ser executada na função de vinculação, não na função de compilação.
A função de compilação pode ter um valor de retorno e o tipo pode ser função ou objeto.
1. A função de retorno geralmente é usada quando a função de compilação não é necessária (vazia), o que é equivalente a registrar uma função de vinculação através do link (define diretamente os atributos do modelo).
2. Retorna um objeto que contém propriedades pré e pós - nos permite controlar quando a função de vinculação é chamada durante a fase de ligação. Para detalhes, consulte os seguintes capítulos sobre funções de pré-ligação e pós-ligação.
10. Função de vinculação
Link da função (escopo, ielement, iattrs, controlador) {…}
A função Link é responsável por registrar o ouvinte do evento DOM e também pode executar operações de atualização do DOM. A função de link será executada após a conclusão da operação de clonagem do modelo. A maior parte da lógica da diretiva é armazenada aqui.
1.Scope - Scope - é usado para registrar relógios (http://docs.angularjs.org/api/ng.$rootscope.scope#$watch).
2.ELELENT - elemento Instância - Elemento usado pela Diretiva. É seguro operar em elementos filhos na função pós -reticulência. Porque os elementos da criança foram vinculados (conectados ao modelo?!).
3.IATTRS - Instância do atributo - A lista de atributos do elemento atual padrão. Compartilhado entre todas as funções de vinculação da diretiva.
4.Controller - Instância do controlador - Se um dos controladores for definido na diretiva do elemento atual, você poderá obter uma instância do controlador aqui. Este controlador é compartilhado entre todas as diretivas, permitindo que cada diretiva trate o controlador como um canal de comunicação entre eles.
Função pré-liga
Execute antes do elemento filho vinculado. Não é seguro fazer a conversão DOM aqui, porque a função de vinculação do compilador pode não localizar os elementos corretos ao vincular.
Função pós-link
Execute após o elemento filho vinculado. É seguro executar a conversão DOM aqui.
11. Atributos
Objeto de atributo - como argumentos em link () ou compile () - é uma maneira de acessar o seguinte:
1. Nomes de atributos padronizados: Como a diretiva, como o NGBind, ela pode se manifestar em muitas formas, como "ng: bind", "x-ng-bind" ... esse objeto de atributo nos permite acessar atributos através da nomeação padrão (camelo).
2. Comunicação entre as diretivas: todas as diretivas compartilham uma instância do objeto de atributo, para que as diretivas possam se comunicar entre as diretivas através de objetos de atributo.
3. Interpolação de suporte: o atributo de interpolação é atribuído a um objeto de atributo, permitindo que outras diretivas leiam o valor interpolado.
4. Observe atributos interpolados: Observe alterações nos valores de atributo através do Att. $ Observe, incluindo interpolação (por exemplo, src = ”{{bar}}"). Não é apenas muito eficaz, mas também é a única maneira de simplesmente obter o valor real. Porque durante o estágio de ligação, a interpolação não foi atribuída (substituída pelo valor real); portanto, ao acessá -lo neste momento, o resultado é indefinido.
<! Doctype html> <html lang = "zh-cn" ng-app = "DirectiveProperty"> <head> <meta charset = "utf-8"> <title> diretiva-attribute-test </title> <style type = "text/css"> .ng-cloak {não; não; } </style> </head> <corpo ng-controller = "myctrl"> <input type = "text" ng-model = "name" value = "myname"/> <p my-attr = "123" diretiva-p2-dd = "{{name}}"> </p> <script sr srrs src = "{{}}}"> </p> <script sr srs type = "text/javascript"> </script> <script type = "text/javascript"> var app = angular.module ("diretiveProperty", []); App.Controller ("myctrl", function ($ scope) {$ scope.name = "meu pequeno dada";}); var DirectiveP2 = App.Directive ("DirectiveP2", function () {return {link: function postLink (escopo, lele, lattr) {console.log ("myattr:" + lattr.myattr); Console.Log ('attdd mudou para' + valor);12. Entenda a transclusão e o escopo
Muitas vezes, precisamos de alguns componentes reutilizáveis. Aqui está um pseudo-código mostrando como um componente de diálogo simples pode funcionar.
<Button ng-click = "show = true"> show </botão> <dialogue visible = "show" no-cancel = "show = false" on -k = "show = false; doSomething ()"> body vai aqui: {{userrame}} é {{{title}}. </Dialog>Clicar no botão "Mostrar" abrirá a caixa de diálogo. A caixa de diálogo tem um título que está vinculado aos dados "nome de usuário" e também há um parágrafo que queremos colocar dentro da caixa de diálogo.
A seguir, é apresentada uma definição de modelo escrita para a caixa de diálogo:
<div ng-show = "show ()"> <h3> {{title}} </h3> <div ng-transclude> </div> <div> <button ng-click = "Onok ()"> Salvar alterações </button> <butt ng-click = "oncancel ()"> fechar </> </button> </> </>Isso não será renderizado corretamente, a menos que façamos algum tratamento especial no escopo.
O primeiro problema que precisamos resolver é que o modelo de diálogo espera que o título seja definido e seja vinculado ao nome de usuário quando inicializado. Além disso, o botão requer duas funções ONOK e ONCANCEL para aparecer no escopo. Isso limita a utilidade do widget ..). Para resolver o problema de mapeamento, as variáveis locais esperadas pelo modelo são criadas pelos seguintes métodos locais (moradores, que são estimados como o escopo no modelo de definição de diretiva):
Escopo: {Title: 'bind', // Configure o título para aceitar o ONOK: 'Expression', // Crie uma função ONOK delegada ONCANCEL: 'Expression', // Crie uma delegada ONCANCEL FUNCTION MOSTRA: 'ACESTOR' // Crie uma função getter/setter para visibilidade.}Criar propriedades locais no escopo de controle traz dois problemas:
1. Isolamento (isolamento do atributo?) - Se o usuário esquecer de definir o título do atributo do elemento no modelo de controle, o título estará vinculado ao atributo "título" do escopo do ancestral (se houver). Isso é imprevisível e indesejável.
2. Transclusão - DOM traduzido pode visualizar os locais (isolar o escopo?) Do controle. Os habitantes locais substituirão as propriedades que realmente precisam estar vinculadas na transclusão. Em nosso exemplo, a propriedade do título no plug -in destrói a propriedade do título da transclusão.
Para resolver esse problema de falta de isolamento de atributos, precisamos definir um escopo isolado para esta diretiva. O escopo isolotado não é herdado do protótipo do escopo da criança (por que é o escopo da criança? Não é escopo dos pais?) Então não precisamos nos preocupar com questões de conflito de atributos (como o irmão do escopo atual).
No entanto, o escopo isolado traz um novo problema: se um DOM traduzido é um filho do escopo isolado do widget, não será capaz de se ligar a nada. Portanto, o escopo traduzido é um escopo infantil do escopo original criado antes que o controle cria o escopo isolado para a propriedade local. O escopo traduzido e isolado pertencem ao nó do irmão (na árvore do escopo).
Isso pode parecer um pouco inesperadamente complicado, mas isso traz pelo menos surpresas para controlar os usuários e controlar os desenvolvedores. (O problema foi resolvido)
Portanto, a definição final da diretiva é aproximadamente a seguinte:
Transclude: true, escopo: {title: 'bind', // configure o título para aceitar o ONOK: 'Expression', // Crie uma função ONOK delegada ONCANCEL: 'Expression', // Crie uma função delegada ONCANCEL mostra: 'Acessor' // Crie uma função getter/setter para visibilidade. // eu tentei isso, mas falhou ... por favor, continue lendo}Eu tentei juntar o código acima em um exemplo completo. Se você copiar diretamente, os resultados esperados não serão alcançados. Mas após um pouco de modificação, o plug-in pode ser executado.
<! Doctype html> <html ng-pp = "dialog"> <head> <meta http-equiv = "content-type" content = "text/html; charset = utf-8"/> <title> diretiva-dialog </title <ete-content = "ie = xa" "/> 1" src = "../ angular.js" type = "text/javascript"> </script> </head> <body> <div ng-antroller = "myctrl"> <button ng-click = "show = true"> show </button> <dialoga visible on-ok = "show = false; MethodInparentsCope ();"> <!-A cancelada acima e o OK são referenciados por & no escopo do isoloato de diretiva. Se a expressão contiver uma função, você precisará vincular a função no escopo dos pais (atualmente myctrl scope) -> o corpo vai aqui: nome de usuário: {{userrame}}, título: {{title}}. <ul> <!-Você também pode jogar assim aqui ~ nomes é o escopo dos pais-> <li ng-repeat = "Nome in nomes"> {{name}} </li> </ul> </dialog> </div> <script type = "text/javascript"> var mymodule = angular.module ("Dialog", []; mymodule.Controller ("myctrl", function ($ scope) {$ scope.names = ["name1", "name2", "name3"]; $ scope.show = false; $ scope.username = "lclao"; $ scope.title = "title"; jogado no escopo dos pais !!! ");};}); myModule.directive('dialog', function factory() { return { priority:100, template:['<div ng-show="visible">', ' <h3>{{title}}</h3>', ' <div ng-transclude></div>', ' <div>', ' <button ng-click="onOk()">OK</button>', ' <button ng-click="onCancel()">Close</button>', ' </div>', ' </div>', ' </div>'].join(""), replace:false, transclude: true, restrict:'E', scope:{ title:"@",//quote the value of the title attribute of the dialog tag onOk:"&",//reference the content of the on-ok attribute of the dialog tag in o formulário da função de wrapper oncancel: "&", // Use o formulário de função do wrapper faz referência ao conteúdo da propriedade na cancelamento da tag de diálogo visível: "@" // refere-se ao valor da propriedade visível da tag de diálogo}}; </script> </body> </html>13. Criando componentes
Geralmente esperamos substituir a diretiva por meio de uma estrutura DOM complexa (o elemento está localizado? O objetivo provavelmente é fazer os pontos complexos internos da diretiva, que parecem impressionantes pontos @_ @). Isso torna a diretiva um atalho para criar aplicativos usando componentes reutilizáveis.
Aqui está um exemplo de componente reutilizável:
<! Doctype html> <html ng-app = "zippymodule"> <head> <meta http-equiv = "content-type" content = "text/html; charset = utf-8"/> <title> zippymodule </title> <meta-content = "ie = = = rodo"/"e", "e", "," e ", e", e ", e" e "e", o chromet = 1 e "e" e "e" e "e" e "e" e "e" e "e" e "e" e "e o título do tipo. <style type = "text/css"> .zippy {borda: 1px Solid Black; Exibição: bloco embutido; Largura: 250px; } .zippy.opened> .title: antes {content: ''; } .zippy.opened> .body {display: block; } .zippy.closed> .title: antes {content: '►'; } .zippy.closed > .body { display: none; } .zippy > .title { background-color: black; color: white; padding: .1em .3em; Cursor: Ponteiro; } .zippy > .body { padding: .1em .3em; } </style> <script src="../angular.js" type="text/javascript"></script></head><body> <div ng-controller="MyCtrl"> Title: <input ng-model="title" type="text"><br/> Text: <textarea ng-model="text"></textarea> <hr/> <div zippy-title="Details: {{title}}...">{{text}}</div> </div> <script type="text/javascript"> var myModule = angular.module("ZippyModule", []); myModule.controller("MyCtrl", function ($scope) { $scope.title = "Here is the title"; $scope.text = "Here is the content... "; }); myModule.directive('zippy', function () { return { template: '<div>' + ' <div>{{title}}</div>' +//This title belongs to the property of the current direct isolate scope ' <div ng-transclude></div>' + //What is here, what is obtained is the property of the parent scope '</div>', replace:true, transclude: true, restrict:'C', scope:{ title:"@zippyTitle"//Bind the zippy-title attribute on the directive element}, link:function(scope,element,attrs) { var title = angular.element(element.children()[0]), opened = false; title.bind("click", toogle); element.addClass("closed"); function toogle() { opened = !opened; element.removeClass(opened ? "closed" : "opened"); element.addClass(opened ? "opened" : "closed"); } } }; }); </script></body></html>