Differenza tra le funzioni 'controller', 'link' e 'compile' quando si definisce una direttiva


393

Alcuni posti sembrano usare la funzione controller per la logica direttiva e altri usano il link. L'esempio di schede nella homepage angolare utilizza controller per uno e collegamento per un'altra direttiva. Qual è la differenza tra i due?


2
Forse una panoramica più completa delle funzioni della direttiva: direttive angolari - quando usare compilazione, controller, pre-link e post-link .
Izhaki,

Risposte:


635

Espanderò un po 'la tua domanda e includerò anche la funzione di compilazione.

  • funzione di compilazione : utilizzare per la manipolazione del modello DOM (ovvero la manipolazione di tElement = elemento modello), quindi le manipolazioni che si applicano a tutti i cloni DOM del modello associato alla direttiva. (Se è necessaria anche una funzione di collegamento (o funzioni pre e post collegamento) e è stata definita una funzione di compilazione, la funzione di compilazione deve restituire le funzioni di collegamento perché l' 'link'attributo viene ignorato se l' 'compile'attributo è definito.)

  • funzione link - normalmente utilizzata per la registrazione di callback listener (es. $watchespressioni nell'ambito) e per l'aggiornamento del DOM (es. manipolazione di iElement = elemento istanza individuale). Viene eseguito dopo la clonazione del modello. Ad esempio, all'interno di un <li ng-repeat...>, la funzione di collegamento viene eseguita dopo che il <li>modello (tElement) è stato clonato (in un iElement) per quel particolare <li>elemento. A $watchconsente a una direttiva di essere informata delle modifiche alle proprietà dell'ambito (un ambito è associato a ciascuna istanza), che consente alla direttiva di eseguire il rendering di un valore di istanza aggiornato sul DOM.

  • funzione controller - deve essere utilizzata quando un'altra direttiva deve interagire con questa direttiva. Ad esempio, nella home page di AngularJS, la direttiva pane deve aggiungersi all'ambito gestito dalla direttiva tabs, quindi la direttiva tabs deve definire un metodo controller (think API) a cui la direttiva pane può accedere / chiamare.

    Per una spiegazione più approfondita delle schede e delle direttive dei riquadri e del perché la direttiva tabs crea una funzione sul suo controller usando this(piuttosto che su $scope), vedere 'this' vs $ scope nei controller AngularJS .

In generale, è possibile inserire metodi, $watchesecc. Nel controller della direttiva o nella funzione di collegamento. Il controller verrà eseguito per primo, il che a volte è importante (vedere questo violino che registra quando le funzioni ctrl e link vengono eseguite con due direttive nidificate). Come Josh ha menzionato in un commento , potresti voler inserire funzioni di manipolazione dell'ambito all'interno di un controller solo per coerenza con il resto del framework.


131
Questa spiegazione dovrebbe essere nei principali documenti di AngularJS o almeno un riferimento ad essa
Dogoku,

7
Questa è una risposta informativa, ma penso che sia difficile da leggere. Forse più punteggiatura e frasi più piccole possono aiutare. Nel complesso, sono grato per la risposta.
Marty Cortez,

Il compilatore $ ignora l'attributo 'link' in presenza di un attributo 'compile'. Ma che dire in presenza di un attributo "controller"? 'Controller' fa sì che il compilatore $ ignori uno o entrambi gli attributi 'link' e 'compile'? È possibile e / o consigliabile utilizzare una "compilazione" insieme a un "controller"?
Carl G,

1
@CarlG, la presenza di un attributo controller non ha alcun effetto sul compilatore $ per quanto riguarda il collegamento e la compilazione. È possibile utilizzare compilazione e controller.
Mark Rajcok,

1
I "listener DOM" NON sono "(ovvero $ watch espressioni sull'ambito)". Uno ascolta il DOM per eventi come mouseover, l'altro l'ambito delle modifiche alle proprietà. Grande differenza.
Dmitri Zaitsev,

56

A complemento della risposta di Mark, la funzione di compilazione non ha accesso all'ambito, ma la funzione di collegamento sì.

Consiglio vivamente questo video; Scrivere direttive di Misko Hevery (il padre di AngularJS), dove descrive le differenze e alcune tecniche. (Differenza tra la funzione di compilazione e la funzione di collegamento alle 14:41 nel video ).


3
+1 per il collegamento al video. È molto informativo.
Rob Kielty,


35
  1. esecuzione del codice prima della compilazione: utilizzare il controller
  2. esecuzione del codice dopo la compilazione: utilizzare il collegamento

Convenzione angolare: scrivere la logica aziendale nel controller e manipolazione DOM nel collegamento.

Oltre a questo, puoi chiamare una funzione controller dalla funzione link di un'altra direttiva, ad esempio hai 3 direttive personalizzate

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

e si desidera accedere agli animali dall'interno della direttiva "leopardo".

http://egghead.io/lessons/angularjs-directive-communication sarà utile per conoscere la comunicazione inter-direttiva


18
msgstr "eseguire il codice prima della compilazione: usa il controller". Questo non è corretto; compilesarà sempre eseguito prima controller .
Izhaki,

Non potreste (almeno non in modo semplice) accedere agli animali dalla vostra direttiva sul leopardo. Le direttive figlio possono accedere ai metodi del controller in una direttiva padre, ma le direttive fratello (come nell'esempio sopra) non possono chiamarsi reciprocamente i controller.
Benjamin White,

2
I leopardi sono davvero un tipo di pantera? Inoltre, su una nota a margine ... Puoi avere un link - E - un controller in una direttiva?
Cody,

1
si leopardo / giaguari sono pantere. e sì, hai link e controller all'interno della direttiva.
Rahul,

1
Dalla guida per sviluppatori Angular: "Best Practice: utilizzare il controller quando si desidera esporre un'API ad altre direttive. Altrimenti utilizzare il collegamento."
Martin van Driel,

6

funzione di compilazione -

  1. viene chiamato prima del controller e della funzione di collegamento.
  2. Nella funzione di compilazione, hai il modello DOM originale in modo da poter apportare modifiche al DOM originale prima che AngularJS ne crei un'istanza e prima che venga creato un ambito
  3. ng-repeat è un esempio perfetto: la sintassi originale è un elemento template, gli elementi ripetuti in HTML sono istanze
  4. Possono esserci più istanze di elementi e un solo elemento modello
  5. Scope non è ancora disponibile
  6. La funzione di compilazione può restituire funzione e oggetto
  7. restituire una funzione (post-link) - equivale a registrare la funzione di collegamento tramite la proprietà link dell'oggetto config quando la funzione di compilazione è vuota.
  8. la restituzione di un oggetto con le funzioni registrate tramite le proprietà pre e post: consente di controllare quando una funzione di collegamento deve essere chiamata durante la fase di collegamento. Di seguito sono riportate informazioni sulle funzioni di pre-collegamento e post-collegamento.

sintassi

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

controllore

  1. chiamato dopo la funzione di compilazione
  2. l'ambito è disponibile qui
  3. è possibile accedere da altre direttive (vedi attributo obbligatorio)

pre-link

  1. La funzione di collegamento è responsabile della registrazione dei listener DOM e dell'aggiornamento del DOM. Viene eseguito dopo la clonazione del modello. Qui è dove verrà messa la maggior parte della logica direttiva.

  2. È possibile aggiornare il dom nel controller usando angular.element, ma ciò non è raccomandato poiché l'elemento è fornito nella funzione link

  3. La funzione pre-link viene utilizzata per implementare la logica che viene eseguita quando js angolare ha già compilato gli elementi figlio ma prima che uno qualsiasi dei post link dell'elemento figlio sia stato chiamato

post-Link

  1. direttiva che ha solo la funzione link, angolare tratta la funzione come post link

  2. il post verrà eseguito dopo la compilazione, il controller e la funzione pre-link, quindi questo è considerato il posto più sicuro e predefinito per aggiungere la tua logica direttiva

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.