Tutorial AngularJS: Demistificarea directivelor personalizate
Publicat: 2022-03-11Odată cu creșterea rapidă a JavaScript ca limbaj de stivă completă, din ce în ce mai multe aplicații utilizează cadre care permit browserului web să gestioneze mai mult procesarea UI, cum ar fi legarea datelor, gestionarea vizualizărilor de date, transformarea datelor și multe alte servicii. Unul dintre cele mai capabile, extensibile și populare cadre este AngularJS, iar una dintre cele mai utile componente ale cadrului AngularJS este ceva numit directivă . AngularJS oferă multe directive utile și, chiar mai important, oferă un cadru bogat pentru crearea de directive personalizate.
Ce este o directivă? Pentru a spune simplu, directivele sunt funcții JavaScript care manipulează și adaugă comportamente elementelor HTML DOM. Directivele pot fi foarte simpliste sau extrem de complicate. Prin urmare, este esențial să obțineți o înțelegere solidă a numeroaselor opțiuni și funcții care le manipulează.
În acest tutorial, cele patru funcții care se execută ca directivă sunt create și aplicate DOM-ului și vor fi oferite exemple. Această postare presupune o anumită familiaritate cu AngularJS și directivele personalizate. Dacă sunteți mai nou la Angular, s-ar putea să vă bucurați de un tutorial despre construirea primei aplicații AngularJS.
Cele patru funcții ale ciclului de viață al directivei AngularJS
Există multe opțiuni care pot fi configurate și modul în care aceste opțiuni sunt legate între ele este important. Fiecare directivă suferă ceva similar cu un ciclu de viață, deoarece AngularJS compilează și conectează DOM-ul. Ciclul de viață al directivei începe și se termină în cadrul procesului de bootstrapping AngularJS, înainte ca pagina să fie randată. În ciclul de viață al unei directive, există patru funcții distincte care se pot executa dacă sunt definite. Fiecare permite dezvoltatorului să controleze și să personalizeze directiva în diferite puncte ale ciclului de viață.
Cele patru funcții sunt: compilare , controller , pre-link și post-Link .
Funcția de compilare permite directivei să manipuleze DOM-ul înainte de a fi compilat și conectat, permițându-i astfel să adauge/elimină/modifica directive, precum și să adauge/elimină/modifica alte elemente DOM.
Funcția de controler facilitează comunicarea directivă. Instrucțiunile pentru frați și copii pot solicita controlorului fraților și părinților lor să comunice informații.
Funcția de pre-link permite manipularea $scope privată înainte de începerea procesului de post-link.
Metoda post-link este metoda principală a directivei.
În directivă, are loc manipularea DOM după compilare, handlerele de evenimente sunt configurate, la fel și ceasurile și alte lucruri. În declarația directivei, cele patru funcții sunt definite astfel.
.directive("directiveName",function () { return { controller: function() { // controller code here... }, compile: { // compile code here... return { pre: function() { // pre-link code here... }, post: function() { // post-link code here... } }; } } })
De obicei, nu sunt necesare toate funcțiile. În majoritatea circumstanțelor, dezvoltatorii vor crea pur și simplu un controler și o funcție de post-link urmând modelul de mai jos.
.directive("directiveName",function () { return { controller: function() { // controller code here... }, link: function() { // post-link code here... } } })
În această configurație, link se referă la funcția post-link .
Indiferent dacă toate sau unele dintre funcții sunt definite, ordinea lor de execuție este importantă, în special execuția lor în raport cu restul aplicației AngularJS.
Execuția funcției directivei AngularJS în raport cu alte directive
Luați în considerare următorul fragment HTML cu directivele parentDir , childDir și grandChildDir aplicate fragmentului HTML.
<div parentDir> <div childDir> <div grandChildDir> </div> </div> </div>
Ordinea de execuție a funcțiilor din cadrul unei directive și în raport cu alte directive este următoarea:
- Faza de compilare
- Funcția de compilare : parentDir
- Funcția de compilare : childDir
- Funcția de compilare : grandChildDir
- Controller și faza de pre-legare
- Funcția controlerului : parentDir
- Funcția de pre- legare: parentDir
- Funcția controlerului : childDir
- Funcția de pre- legare: childDir
- Funcția controlerului : grandChildDir
- Funcția de pre- legare: grandChildDir
- Faza de post-legare
- Funcție post-link : grandChildDir
- Funcție post-link : childDir
- Funcție post-link : parentDir
AngularJS Directiva Funcție Explicație: Deep Dive
Faza de compilare are loc mai întâi. În esență, faza de compilare atașează ascultătorii de evenimente la elementele DOM. De exemplu, dacă un anumit element DOM este legat de o proprietate $scope , ascultătorul de evenimente care îi permite să fie actualizat cu valoarea proprietății $scope este aplicat elementului DOM. Procesul de compilare începe cu elementul DOM rădăcină de la care aplicația AngularJS a fost bootstrap și traversează ramurile DOM folosind o traversare în profunzime, compilând mai întâi un părinte, apoi copiii săi până la nodurile frunzelor.
Odată ce compilarea este completă, directivele nu mai pot fi adăugate sau eliminate din DOM (deși există o cale de ocolire prin utilizarea directă a serviciului de compilare. Următoarea fază este apelarea controlorilor și a funcțiilor de pre-link pentru toate directivele. Când controlerul este complet). este apelat, $scope este disponibil și poate fi folosit. Elementul $ injectat în controler conține șablonul compilat, dar nu include conținutul copil transclus (conținutul transclus este conținutul dintre etichetele HTML de început și de sfârșit pe care se află directiva Prin definiție, controlorii dintr-un model MVC pur și simplu trec modelul în vizualizare și definesc funcții pentru gestionarea evenimentelor. Prin urmare, controlerul unei directive nu ar trebui să modifice DOM-ul directivei din două motive: încalcă scopul controler, iar conținutul copil transclus nu a fost adăugat la DOM. Deci, ce face un controler dincolo de modificarea $scope ? Controlerul permite directivelor copil să comunice cu directivele părintelui. Funcția controler în sine ar trebui să fie considerată ca un obiect controler care va fi trecut în funcția de post-link a directivei child dacă directiva copil solicită acest lucru. Prin urmare, controlerul este utilizat în mod obișnuit pentru a facilita comunicarea directivelor prin crearea unui obiect cu proprietăți și metode care pot fi utilizate de directivele sale frate și copil. Directiva părinte nu poate determina dacă o directivă copil poate solicita controlerul său, așa că cel mai bine este să limitați codul din această metodă la funcții și proprietăți care pot fi utilizate în siguranță de directivele copil.
După funcția de controler, funcția de pre-link se execută. Funcția de pre-link este misterioasă pentru mulți oameni. Dacă citiți o mare parte din documentația de pe Internet și din cărți, oamenii scriu că această funcție este folosită doar în circumstanțe rare și că oamenii nu vor avea aproape niciodată nevoie de ea. Aceleași explicații nu reușesc să ofere un exemplu de situație în care ar putea fi folosită.

Funcția de pre-link nu este deloc complicată. În primul rând, dacă revizuiți codul sursă AngularJS, veți găsi un exemplu excelent al funcției de pre-link: directiva ng-init îl folosește. De ce? Este pur și simplu o metodă grozavă de a executa cod privat care implică $scope ; cod care nu poate fi apelat de directivele de frați și copii. Spre deosebire de funcția de controler, funcția de pre-link nu este transmisă în directive. Prin urmare, poate fi folosit pentru a executa cod care modifică domeniul $ al directivei sale. Directiva ng-init face exact acest lucru. Când funcția de pre-link pentru ng-init se execută, pur și simplu execută JavaScript trecut în directivă în raport cu $scope -ul directivei. Rezultatul execuției este disponibil prin moștenirea prototipului $scope la directivele copil în timpul execuțiilor funcțiilor de control, pre-link și post-link, dar fără a oferi acces la acele directive copil pentru a reexecuta codul în pre-legare a părintelui. funcția de legătură. De asemenea, directiva poate avea nevoie să execute alt cod care nu are legătură cu $scope pe care dorește să-l păstreze privat.
Unii dezvoltatori AngularJS cu experiență ar spune că acest cod privat ar putea fi încă plasat în controler și apoi să nu fie apelat de directivele copil. Acest argument ar fi valabil dacă directiva va fi folosită doar de dezvoltatorul original care a codificat-o, dar dacă directiva va fi distribuită și reutilizată de alți dezvoltatori, atunci încapsularea codului privat în funcția de pre-link ar putea fi foarte benefică. Deoarece dezvoltatorii nu știu niciodată cum va fi reutilizată directiva lor de-a lungul timpului, protejarea codului privat de a fi executat de către o directivă copil este o abordare bună pentru încapsularea codului directivei. Consider că este o practică bună să plasați codul public de comunicare directiv în funcția de controler și codul privat în funcția de pre-link. La fel ca controlerul, pre-linkul nu ar trebui să efectueze niciodată manipularea DOM și nici să execute o funcție de transcludere, deoarece conținutul directivelor copil nu a fost încă legat.
Pentru fiecare directivă, controlerul și funcția de pre-link se execută înainte de controler și funcția de pre-link a directivelor sale secundare. Odată ce controlerul și faza de pre-legare pentru toate directivele sunt finalizate, AngularJS începe faza de conectare și execută funcțiile post-link pentru fiecare directivă. Faza de conectare se desfășoară opus fluxurilor de execuție de compilare, control și pre-link, începând cu nodurile DOM frunză și mergând până la nodul DOM rădăcină. Traversarea DOM post-link urmează o cale în principal pe adâncime. Pe măsură ce fiecare directivă copil este legată, funcția sa de post-link este executată.
Funcția post-link este funcția cel mai frecvent implementată în directivele personalizate AngularJS. În această funcție, aproape orice lucru rezonabil poate fi făcut. DOM-ul poate fi manipulat (doar pentru el însuși și pentru elementele copil), $scope este disponibil, obiectul controler pentru directivele părinte poate fi utilizat, funcțiile transclude pot fi executate etc. Cu toate acestea, există câteva limitări. Noile directive nu pot fi adăugate la DOM deoarece nu vor fi compilate. În plus, toate manipulările DOM trebuie efectuate folosind funcțiile DOM. Simpla apelare a funcției html de pe elementul DOM și transmiterea unui cod HTML nou va elimina toți handlerele de evenimente adăugate în timpul procesului de compilare. De exemplu, acestea nu vor funcționa conform așteptărilor:
element.html(element.html());
sau
element.html(element.html() + "<div>new content</div>");
Codul nu va determina modificarea HTML-ului, dar reatribuirea versiunii șir a elementelor DOM va elimina toți gestionanții de evenimente creați în timpul procesului de compilare. În mod obișnuit, funcția de post-link este utilizată pentru a conecta handlere de evenimente, $watch es și $observe s.
Odată ce toate funcțiile post-link sunt executate, $scope este aplicat structurii DOM compilate și legate, iar pagina AngularJS prinde viață.
Diagrama de funcții ale directivei
Iată o diagramă care listează scopul fiecărei funcții, ceea ce este disponibil atunci când se execută și cele mai bune practici despre cum să utilizați fiecare funcție în mod corespunzător.
Execuţie Ordin | Directivă Funcţie | DOM | Transclude | $scop | Apelabil de Copil |
---|---|---|---|---|---|
1 | compila | DOM nu a fost compilat, dar șablonul a fost încărcat în zona de conținut al elementului DOM. Directivele pot fi adăugate și eliminate. DOM poate fi manipulat atât cu funcții DOM, cât și cu înlocuirea șirurilor HTML. | Funcția Transclude este disponibilă, dar este depreciată și nu ar trebui apelată. | Nu e disponibil. | Funcția nu poate fi apelată de elementele copil. |
2 | controlor | Elementul DOM compilat este disponibil, dar nu trebuie modificat. Conținutul copil transclus nu a fost adăugat la elementul DOM. Nu ar trebui să apară modificări DOM, deoarece acesta este un controler și conținutul copil transclus nu a fost încă conectat. | Funcția de transcludere este disponibilă, dar nu trebuie apelată. | $scope este disponibil și poate fi utilizat. Parametrii funcției sunt injectați folosind serviciul $injector . | Funcția este transmisă în funcțiile de legare a directivei copil și este apelabilă de către acestea. |
3 | pre-link | Elementul DOM compilat este disponibil, dar nu ar trebui modificat deoarece elementele DOM din directiva copil nu au fost încă conectate. | Funcția de transcludere este disponibilă, dar nu trebuie apelată. | $scope este disponibil și poate fi modificat. | Funcția nu este apelabilă de directivele copil. Dar poate apela controlorii directivelor părinte. |
4 | post-link | Elementele DOM compilate și elementele DOM ale directivei copil sunt disponibile. DOM poate fi modificat numai cu funcții DOM (fără înlocuire HTML) și poate fi adăugat numai conținut care nu necesită compilare. Nu este permisă adăugarea/eliminarea de directive. | Funcția de transcludere este disponibilă și poate fi apelată. | $scope este disponibil și poate fi utilizat. | Nu poate fi apelat de către copiii directivei, dar poate apela controlorul directivelor părinților. |
rezumat
În acest tutorial despre directivele AngularJS, am învățat despre scopul, ordinea de execuție și capacitățile și utilizările generale pentru fiecare dintre cele patru funcții directive: compilare , controller , pre-link și post-link . Dintre cele patru funcții, controller și post-link sunt cele mai frecvent utilizate, dar pentru directivele mai complexe care trebuie să aibă un control mai mare asupra DOM-ului sau au nevoie de un mediu de execuție cu scop privat, pot fi utilizate funcțiile de compilare și pre-link.