A fost una din acele zile când eram ocupat să lucrez la noi funcții pentru proiectul meu de birou. Dintr-o dată, ceva mi-a atras atenția:

Tot ce trebuie sa stiti despre ng template ng content ng container si
DOM final redat în Angular

În timp ce inspectam DOM, am văzut ngcontent fiind aplicat pe elemente de Angular. Hmm … dacă conțin elementele din DOM-ul final, atunci la ce folosește <ng-container>? În acel moment m-am confundat între <ng-container> și <ng-content>.

În căutarea de a cunoaște răspunsurile la întrebările mele, am descoperit conceptul de <ng-template>. Spre surprinderea mea, a existat și *ngTemplateOutlet. Mi-am început călătoria căutând claritate despre două concepte, dar acum aveam patru dintre ele, sunând aproape la fel!

Ai fost vreodată în această situație? Dacă da, atunci vă aflați în locul potrivit. Așadar, fără alte întrebări, să le luăm pe rând.

1.

După cum sugerează și numele <ng-template> este un element șablon pe care Angular îl folosește cu directive structurale (*ngIf, *ngFor, [ngSwitch] și directivele personalizate).

Aceste elemente șablon funcționează numai în prezența directivelor structurale. Unghiular înfășoară elementul gazdă (căruia i se aplică directiva) în interior <ng-template> și consumă <ng-template> în DOM-ul terminat prin înlocuirea acestuia cu comentarii de diagnosticare.

Luați în considerare un exemplu simplu de *ngIf:

1611898328 740 Tot ce trebuie sa stiti despre ng template ng content ng container si
Exemplul 1– Proces unghiular de interpretare a directivelor structurale

Arătată mai sus este interpretarea unghiulară a *ngIf. Angular pune elementul gazdă la care se aplică directiva <ng-template> și păstrează gazda așa cum este. DOM-ul final este similar cu ceea ce am văzut la începutul acestui articol:

Tot ce trebuie sa stiti despre ng template ng content ng container si
Exemplul 1– DOM final redat

Utilizare:

Am văzut cum folosește Angular <ng-template> dar dacă vrem să-l folosim? Deoarece aceste elemente funcționează numai cu o directivă structurală, putem scrie ca:

1611898328 385 Tot ce trebuie sa stiti despre ng template ng content ng container si
Exemplul 2– Folosind

Aici home este un boolean proprietatea componentei setată la true valoare. Ieșirea codului de mai sus în DOM:

1611898329 144 Tot ce trebuie sa stiti despre ng template ng content ng container si
Exemplul 2– DOM final redat

Nimic nu a fost redat! 🙁

Dar de ce nu putem vedea mesajul nostru chiar și după utilizare <ng-template> corect cu o directivă structurală?

Acesta a fost rezultatul scontat. După cum am discutat deja, Angular înlocuiește <ng-template> cu comentarii de diagnostic. Fără îndoială, codul de mai sus nu ar genera nicio eroare, deoarece Angular este perfect în cazul de utilizare. N-ai să afli niciodată ce s-a întâmplat exact în culise.

Să comparăm cele două DOM-uri de mai sus care au fost redate de Angular:

Tot ce trebuie sa stiti despre ng template ng content ng container si
1611898329 144 Tot ce trebuie sa stiti despre ng template ng content ng container si
Exemplul 1 vs. Exemplul 2

Dacă privești cu atenție, există unul etichetă de comentariu suplimentară în DOM-ul final al Exemplul 2. Codul interpretat de Angular a fost:

1611898329 483 Tot ce trebuie sa stiti despre ng template ng content ng container si
Proces de interpretare unghiulară pentru Exemplul 2

Unghiular a încheiat gazda <ng-template> în interiorul altuia <ng-template> și a convertit nu numai exteriorul <ng-template> la comentariile de diagnostic dar și la cele interioare! Acesta este motivul pentru care nu ați putut vedea niciun mesaj.

Pentru a scăpa de acest lucru există două moduri de a obține rezultatul dorit:

1611898329 501 Tot ce trebuie sa stiti despre ng template ng content ng container si
Utilizarea corectă a

Metoda 1:

În această metodă, furnizați Angular formatul de-zahărit care nu necesită prelucrări suplimentare. De data aceasta, Angular s-ar converti doar <ng-template> la comentarii dar lasă neatins conținutul din interior (nu mai sunt în niciunul <ng-template> precum au fost în cazul anterior). Astfel, va reda conținutul corect.

Pentru a afla mai multe despre cum să utilizați acest format cu alte directive structurale, consultați acest lucru articol.

Metoda 2:

Acesta este un format destul de nevăzut și este rar folosit (folosind doi frați <ng-template>). Aici oferim o referință șablon la *ngIf în then pentru a-i spune ce șablon trebuie utilizat dacă condiția este adevărată.

Folosind multiple <ng-template> așa nu este recomandat (ați putea folosi <ng-container> în schimb) întrucât nu pentru asta sunt destinate. Acestea sunt utilizate ca un container pentru șabloane care pot fi refolosite în mai multe locuri. Vom acoperi mai multe despre acest lucru într-o secțiune ulterioară a acestui articol.

2.

Ați scris sau ați văzut vreodată un cod asemănător cu acesta:

1611898329 972 Tot ce trebuie sa stiti despre ng template ng content ng container si
Exemplul 1

Motivul pentru care mulți dintre noi scriem acest cod este incapacitatea de a utiliza mai multe directive structurale pe un singur element gazdă în Angular. Acum acest cod funcționează bine, dar introduce mai multe goluri suplimentare <div> în DOM dacă item.id este o valoare falsă care s-ar putea să nu fie necesară.

1611898329 962 Tot ce trebuie sa stiti despre ng template ng content ng container si
Exemplul 1– DOM final redat

S-ar putea să nu fii îngrijorat pentru un exemplu simplu ca acesta, dar pentru o aplicație uriașă care are un DOM complex (pentru a afișa zeci de mii de date), acest lucru ar putea deveni deranjant, deoarece elementele ar putea avea ascultători atașați la ei, care vor fi încă acolo în DOM ascultând evenimente.

Ce este și mai rău este nivelul de cuibărit pe care trebuie să-l faci pentru a-ți aplica stilul (CSS)!

1611898329 980 Tot ce trebuie sa stiti despre ng template ng content ng container si
Imagine din: În interiorul Unbounce

Fără griji, avem <ng-container> la salvare!

Angularul <ng-container> este un element de grupare care nu interferează cu stilurile sau aspectul, deoarece Angular nu o pune în DOM.

Deci, dacă ne scriem Exemplul 1 cu <ng-container>:

1611898329 866 Tot ce trebuie sa stiti despre ng template ng content ng container si
Exemplul 1 cu

Obținem DOM-ul final ca:

1611898329 284 Tot ce trebuie sa stiti despre ng template ng content ng container si
DOM final redat cu

Vezi că am scăpat de cei goi <div>s. Ar trebui să folosim <ng-container> când vrem doar să aplicăm mai multe directive structurale fără a introduce niciun element suplimentar în DOM-ul nostru.

Pentru mai multe informații, consultați documente. Există un alt caz de utilizare în care este folosit pentru a injecta un șablon dinamic într-o pagină. Voi acoperi acest caz de utilizare în ultima secțiune a acestui articol.

3.

Acestea sunt utilizate pentru a crea componente configurabile. Aceasta înseamnă că componentele pot fi configurate în funcție de nevoile utilizatorului său. Acest lucru este bine cunoscut sub numele de Proiecție de conținut. Componentele care sunt utilizate în bibliotecile publicate folosesc <ng-content> pentru a se face configurabili.

Luați în considerare un simplu <project-content> componentă:

1611898329 546 Tot ce trebuie sa stiti despre ng template ng content ng container si
Exemplul 1– definiție
1611898329 989 Tot ce trebuie sa stiti despre ng template ng content ng container si
Proiecție de conținut cu componentă

Conținutul HTML a fost transmis în etichetele de deschidere și închidere ale <project-content> componenta este conținutul care trebuie proiectat. Asta numim noi Proiecție de conținut. Conținutul va fi redat în interiorul fișierului <ng-content> în cadrul componentei. Acest lucru permite consumatorului de <project-content> componentă pentru a trece orice subsol personalizat în cadrul componentei și al controlului exact cum vor să fie redate.

Proiecții multiple:

Ce se întâmplă dacă ați putea decide ce conținut ar trebui plasat unde? În loc de fiecare conținut proiectat în interiorul unui singur <ng-content>, puteți controla, de asemenea, modul în care conținutul va fi proiectat cu select atribut al <ng-content>. Este nevoie de un selector de elemente pentru a decide ce conținut să proiecteze în interiorul unui anumit <ng-content>.

Iată cum:

1611898329 142 Tot ce trebuie sa stiti despre ng template ng content ng container si
Exemplul 2– Proiecție multi-conținut cu actualizat

Am modificat <project-content> definiție pentru a efectua proiecție multi-conținut. select atributul selectează tipul de conținut care va fi redat în interiorul unui anumit <ng-content>. Aici avem mai întâi select a reda antetul h1 element. Dacă conținutul proiectat nu are nr h1 element nu va reda nimic. În mod similar, al doilea select caută o div. Restul conținutului este redat în ultimul <ng-content> Cu nu select.

Apelarea componentei va arăta astfel:

1611898329 854 Tot ce trebuie sa stiti despre ng template ng content ng container si
Exemplul 2– Apelarea componentei în componenta părinte

4. * ngTemplateOutlet

… Sunt folosite ca un container pentru șabloane care pot fi refolosite în mai multe locuri. Vom acoperi mai multe despre acest lucru într-o secțiune ulterioară a acestui articol.

… Există un alt caz de utilizare în care este folosit pentru a injecta un șablon dinamic într-o pagină. Voi acoperi acest caz de utilizare în ultima secțiune a acestui articol.

Aceasta este secțiunea în care vom discuta cele două puncte de mai sus menționate anterior. *ngTemplateOutlet este utilizat pentru două scenarii – pentru a insera un șablon comun în diferite secțiuni ale unei vizualizări, indiferent de bucle sau condiții și pentru a crea o componentă foarte configurată.

Reutilizarea șablonului:

Luați în considerare o vizualizare în care trebuie să inserați un șablon în mai multe locuri. De exemplu, o siglă a companiei care trebuie plasată pe un site web. O putem realiza scriind șablonul pentru logo o dată și refolosindu-l peste tot în vizualizare.

Următorul este fragmentul de cod:

1611898329 736 Tot ce trebuie sa stiti despre ng template ng content ng container si
Exemplul 1– Reutilizarea șablonului

După cum puteți vedea, am scris doar șablonul de logo o dată și l-am folosit de trei ori pe aceeași pagină cu o singură linie de cod!

*ngTemplateOutlet acceptă, de asemenea, un obiect context care poate fi transmis pentru a personaliza rezultatul șablonului comun. Pentru mai multe informații despre obiectul context, consultați oficialul documente.

Componente personalizabile:

Al doilea caz de utilizare pentru *ngTemplateOutlet este componente foarte personalizate. Luați în considerare exemplul nostru anterior de <project-content>componentă cu unele modificări:

1611898329 281 Tot ce trebuie sa stiti despre ng template ng content ng container si
Exemplul 2– Realizarea unei componente personalizabile, project-content.html

Mai sus este versiunea modificată a <project-content> componentă care acceptă trei proprietăți de intrare –headerTemplate, bodyTemplate, footerTemplate. Urmează fragmentul pentru project-content.ts:

1611898329 142 Tot ce trebuie sa stiti despre ng template ng content ng container si
Exemplul 2– Realizarea componentelor personalizabile, project-content.ts

Ceea ce încercăm să realizăm aici este să arătăm antetul, corpul și subsolul așa cum am primit de la componenta părinte a <project-content>. Dacă nu este furnizat vreunul dintre ele, componenta noastră va afișa șablonul implicit în locul său. Astfel, crearea unei componente foarte personalizate.

Pentru a utiliza componenta noastră recent modificată:

1611898329 962 Tot ce trebuie sa stiti despre ng template ng content ng container si
Exemplul 2– Utilizarea componentei nou modificate

Acesta este modul în care vom transmite referințele șablonului la componenta noastră. Dacă oricare dintre ele nu este trecută, atunci componenta va reda șablonul implicit.

ng-content vs. * ngTemplateOutlet

Ambele ne ajută să obținem componente foarte personalizate, dar pe care să le alegem și când?

Se vede clar că *ngTemplateOutlet ne oferă o putere mai mare de a afișa șablonul implicit dacă nu este furnizat niciunul.

Nu este cazul ng-content. Redă conținutul așa cum este. Cu maxim, puteți împărți conținutul și le puteți reda în diferite locații ale vizualizării cu ajutorul select atribut. Nu puteți reda condiționat conținutul din interior ng-content. Trebuie să afișați conținutul primit de la părinte fără mijloace de a lua decizii pe baza conținutului.

Cu toate acestea, alegerea dintre cele două depinde în totalitate de cazul dvs. de utilizare. Cel puțin acum avem o nouă armă *ngTemplateOutlet în arsenalul nostru, care oferă mai mult control asupra conținutului, pe lângă caracteristicile ng-content!