Alt hvad du behøver at vide om ng-skabelon, ng-indhold, ng-container og * ngTemplateOutlet i vinkel

Det var en af ​​de dage, hvor jeg havde travlt med at arbejde på nye funktioner til mit kontorprojekt. Pludselig fangede noget min opmærksomhed:

Mens jeg inspicerede DOM, så jeg, at det ngcontentblev anvendt på elementer af Angular. Hmm ... hvis de indeholder elementerne i den endelige DOM, hvad nytter det så ? På det tidspunkt blev jeg forvirret mellem og .

I jagten på at kende svarene på mine spørgsmål opdagede jeg begrebet . Til min overraskelse var der også *ngTemplateOutlet. Jeg startede min rejse med at søge klarhed omkring to koncepter, men nu havde jeg fire af dem, der lyder næsten det samme!

Har du nogensinde været i denne situation? Hvis ja, så er du på det rette sted. Så lad os tage dem en efter en uden videre.

1.

Som navnet antyder er en skabelon element, Kantede anvendelser med strukturelle direktiver ( *ngIf, *ngFor, [ngSwitch]og brugerdefinerede direktiver).

Disse skabelonelementer fungerer kun i nærværelse af strukturdirektiver . Vinkel indpakker værtselementet (som direktivet gælder for) indeniog forbruger deni den færdige DOM ved at erstatte det med diagnostiske kommentarer.

Overvej et simpelt eksempel på *ngIf:

Vist ovenfor er den vinklede fortolkning af *ngIf. Angular placerer værtselementet, som direktivet anvendes på, inden for og holder værten, som den er. Den endelige DOM svarer til det, vi har set i begyndelsen af ​​denne artikel:

Anvendelse:

Vi har set, hvordan Angular bruger, men hvad hvis vi vil bruge det? Da disse elementer kun fungerer med et strukturdirektiv, kan vi skrive som:

Her homeer en booleanegenskab for komponenten indstillet til trueværdi. Output af ovenstående kode i DOM:

Intet blev gengivet! :(

Men hvorfor kan vi ikke se vores budskab, selv efter at have brugt korrekt med et strukturdirektiv?

Dette var det forventede resultat. Som vi allerede har diskuteret, erstatter Angular det med diagnostiske kommentarer. Uden tvivl ville ovenstående kode ikke generere nogen fejl, da Angular er helt fint med din brugssag. Du ville aldrig få at vide, hvad der nøjagtigt skete bag kulisserne.

Lad os sammenligne de to ovennævnte DOM'er, der blev gengivet af Angular:

Hvis du følger nøje med, er der et ekstra kommentarmærke i den endelige DOM i eksempel 2 . Koden, som Angular fortolkede, var:

Vinklet pakkede din vært ind i en anden og konverterede ikke kun de ydre til diagnostiske kommentarer, men også den indre! Dette er grunden til, at du ikke kunne se nogen af ​​din besked.

For at slippe af med dette er der to måder at få det ønskede resultat på:

Metode 1:

I denne metode giver du Angular det de-sukkerformat, der ikke behøver yderligere behandling. Denne gang konverterede Angular kun til kommentarer, men efterlader indholdet inde i det uberørt (de er ikke længere inde i nogen som de var i det foregående tilfælde). Således gengiver det indholdet korrekt.

For at vide mere om, hvordan du bruger dette format med andre strukturelle direktiver, henvises til denne artikel.

Metode 2:

Dette er et ganske uset format og bruges sjældent (ved hjælp af to søskende ). Her giver vi en skabelonhenvisning til *ngIfi dens for thenat fortælle den, hvilken skabelon der skal bruges, hvis betingelsen er sand.

Brug af flere som dette anbefales ikke (du kan bruge i stedet), da dette ikke er det, de er beregnet til. De bruges som en container til skabeloner, der kan genbruges flere steder. Vi vil dække mere om dette i et senere afsnit af denne artikel.

2.

Har du nogensinde skrevet eller set kode, der ligner denne:

Årsagen til, at mange af os skriver denne kode, er manglende evne til at bruge flere strukturelle direktiver på et enkelt værtselement i Angular. Nu fungerer denne kode fint, men den introducerer flere ekstra tomme i DOM, hvis der item.ider en falsk værdi, som muligvis ikke kræves.

Man er måske ikke bekymret for et simpelt eksempel som dette, men for en enorm applikation, der har en kompleks DOM (for at vise titusinder af data), kan dette blive besværligt, da elementerne måske har lyttere knyttet til sig, som stadig vil være der i DOM lytter til begivenheder.

Hvad der er endnu værre er niveauet af indlejring, som du skal gøre for at anvende din styling (CSS)!

Ingen bekymringer, vi er nødt til at redde!

Vinklen er et grupperingselement, der ikke forstyrrer typografier eller layout, fordi Angular ikke placerer det i DOM .

Så hvis vi skriver vores eksempel 1 med :

Vi får den endelige DOM som:

Ser vi slippe af med de tomme s. Vi skal bruge, når vi bare vil anvende flere strukturelle direktiver uden at indføre noget ekstra element i vores DOM.

For flere oplysninger henvises til doku- menterne. Der er en anden brugssag, hvor den bruges til at injicere en skabelon dynamisk på en side. Jeg vil dække denne brugssag i sidste afsnit af denne artikel.

3.

De bruges til at oprette konfigurerbare komponenter. Dette betyder, at komponenterne kan konfigureres afhængigt af brugerens behov. Dette er kendt som Content Projection . Komponenter, der bruges i offentliggjorte biblioteker, bruger for at gøre sig selv konfigurerbare.

Overvej en simpel komponent:

HTML-indholdet, der sendes i komponentens åbnings- og lukemærker , er det indhold, der skal projiceres. Dette er hvad vi kalder indholdsprojektion . Indholdet gengives inde i komponenten. Dette gør det muligt for forbrugeren af komponent at passere enhver brugerdefineret sidefod i komponenten og kontrollere nøjagtigt, hvordan de ønsker, at den skal gengives.

Flere fremskrivninger:

Hvad hvis du kunne beslutte, hvilket indhold der skulle placeres hvor? I stedet for alt indhold, der projiceres inde i en enkelt , kan du også kontrollere, hvordan indholdet bliver projiceret med selectattributten . Det tager en elementvælger at afgøre, hvilket indhold der skal projiceres inde i en bestemt .

Sådan gør du:

Vi har ændret definitionen til at udføre projektion med flere indhold. Den selectattribut vælger typen af indhold, der vil blive gjort i en bestemt . Her skal vi først selectgengive headerelement h1. Hvis det projicerede indhold ikke har noget h1element, gengiver det ikke noget. Tilsvarende selectser det andet efter en div. Resten af ​​indholdet gengives inden i det sidste med nr select.

At ringe til komponenten vil se ud:

4. * ngTemplateOutlet

... De bruges som en container til skabeloner, der kan genbruges flere steder. Vi vil dække mere om dette i et senere afsnit af denne artikel.

... Der er en anden brugssag, hvor den bruges til at indsprøjte en skabelon dynamisk på en side. Jeg vil dække denne brugssag i sidste afsnit af denne artikel.

Dette er det afsnit, hvor vi vil diskutere de ovennævnte to punkter, der er nævnt før. *ngTemplateOutletbruges til to scenarier - at indsætte en fælles skabelon i forskellige sektioner i en visning uanset sløjfer eller tilstand og at lave en meget konfigureret komponent.

Genbrug af skabeloner:

Overvej en visning, hvor du skal indsætte en skabelon flere steder. For eksempel et firmalogo, der skal placeres på et websted. Vi kan opnå det ved at skrive skabelonen til logoet en gang og genbruge det overalt i visningen.

Følgende er kodestykket:

Som du kan se, skrev vi netop logo-skabelonen en gang og brugte den tre gange på samme side med en enkelt kodelinje!

*ngTemplateOutletaccepterer også et kontekstobjekt, som kan sendes til at tilpasse den fælles skabelonoutput. For mere information om kontekstobjektet henvises til de officielle dokumenter.

Komponenter, der kan tilpasses:

Den anden brugssag til *ngTemplateOutleter meget tilpassede komponenter. Overvej vores tidligere eksempel på komponent med nogle ændringer:

Ovenfor er den modificeret version af komponent, som accepterer tre input egenskaber -  headerTemplate, bodyTemplate, footerTemplate. Følgende er uddraget til project-content.ts:

Det, vi forsøger at opnå her, er at vise sidehoved, krop og sidefod som modtaget fra den overordnede komponent i . Hvis en af ​​dem ikke leveres, viser vores komponent standardskabelonen i stedet for. Således opretter en meget tilpasset komponent.

Sådan bruges vores nyligt modificerede komponent:

Sådan overfører vi skabelon-ref til vores komponent. Hvis en af ​​dem ikke bliver bestået, gengiver komponenten standardskabelonen.

ng-indhold vs. * ngTemplateOutlet

De hjælper os begge med at opnå højt tilpassede komponenter, men hvad skal vi vælge, og hvornår?

Det kan tydeligt ses, der *ngTemplateOutletgiver os noget mere magt til at vise standardskabelonen, hvis der ikke er nogen.

Dette er ikke tilfældet med ng-content. Det gengiver indholdet som det er. Du kan maksimalt dele indholdet og gengive det på forskellige steder i din visning ved hjælp af selectattribut. Du kan ikke betinget gengive indholdet inden for ng-content. Du er nødt til at vise det indhold, der modtages fra forælderen uden mulighed for at træffe beslutninger baseret på indholdet.

Valget af at vælge blandt de to afhænger dog helt af din brugssag. I det mindste nu har vi et nyt våben *ngTemplateOutleti vores arsenal, som giver mere kontrol over indholdet ud over funktionerne i ng-content!