I Angular er en komponent en særlig direktiv, og dens særlige egenskab er, at den har sin egen skabelon (html) og stil (css). Derfor kan brug af komponenter gøre vores kode meget adskilt, genanvendelig og let at udvide os. De sædvanlige komponenter defineres som følger:
demo.component.ts:
demo.component.html:
demo.component.scss:
Når vi refererer til komponenten, gengives det parsede indhold af komponenten:
Antag, at komponenten skal acceptere eksternt projiceret indhold, hvilket betyder, at komponenten ender med at præsentere mere end blot det, den definerer. På nuværende tidspunkt er hovedpersonen i denne artikel inviteretng-indhold。
Simpel projektion
Lad os starte med det simpleste: tilføj den modificerede demo.component.html og demo.component.scss til demo.component.html, som følger:
demo.component.html:
demo.component.scss:
For effektens skyld er beholderens baggrundsfarve bevidst defineret som orange.
På dette tidspunkt kan vi kaste indhold udefra, når vi refererer til komponenten, og det eksterne indhold vil blive vist i det orange område:
Målrettet projektion
Hvis der er flere på samme tid, hvordan vil det eksterne indhold så blive projiceret?
Lad os først se på et eksempel, for at skelne dem tilføjede jeg et blåt område, den modificerede demo.component.html og demo.component.scss som følger:
demo.component.html:
demo.component.scss:
For at referere til komponenten:
På dette tidspunkt vil vi se, at det eksterne indhold projiceres til det blå område:
Selvfølgelig, hvis du sætter det orange områdenummer efter det blå områdekode, vil det eksterne indhold blive projiceret til det orange område:
Så ud fra eksemplet ovenfor kan vi se, at hvis der også er en simpel , så vil det eksterne indhold blive projiceret i den sidste i komponentskabelonen.
Så med dette problem kan vi undre os over, om vi kan projicere eksternt indhold på en målrettet måde? Svaret er selvfølgelig ja.
For at håndtere dette, støt énmarkereEgenskaber, der gør det muligt at projicere specifikt indhold et bestemt sted. Denne egenskab understøtter CSS-selektorer (tag-vælger, klassevælger, attributvælger、... ) for at matche det, du ønsker. Hvis der ikke er sat nogen select-attribut på ng-content, vil den modtage det fulde indhold, eller det indhold, der ikke matcher noget andet ng-content-element.
Ser man direkte på eksemplet, er de modificerede demo.component.html og demo.component.scss som følger:
demo.component.html:
demo.component.scss:
Som du kan se fra ovenstående kode, vil det blå område modtage den del af tagheaderen, det røde område vil modtage den del af div'en med klassen "demo2", det grønne område vil modtage den del af div'en med ejendomsnavnet "demo3", og det orange område vil modtage resten af det eksterne indhold (start, jeg er indholdet af den eksterne embed, slut).
For at referere til komponenten:
På dette tidspunkt vil vi se det eksterne indhold projiceret ind i den specificerede .
Udvid viden
ngProjectAs
Nu ved vi, at select-egenskaben ng-content tillader dig at angive, at eksternt indhold projiceres ind i en given .
For korrekt at projicere indhold baseret på select-attributtet er der en begrænsning – uanset om det er en tagheader, en div med en klasse af "demo2" eller en div med egenskabsnavnet "demo3", er disse tags alle direkte undernoder af komponenttagget.
Hvad ville der ske, hvis det ikke var for at være en direkte subnode? Lad os blot ændre koden, der refererer til demo-komponentkomponenten, lægge tagheaderen i en div og ændre den som følger:
På dette tidspunkt ser vi, at tabulator-headerdelen af indholdet ikke længere projiceres i det blå område, men i det orange område. Årsagen er, at <ng-content select="header"></ng-content> ikke kan matche den forrige tag-header, så denne del af indholdet projiceres til det <ng-content></ng-content> orange område.
For at løse dette problem skal vi bruge egenskaben ngProjectAs, som kan anvendes på ethvert element. Detaljerne er som følger:
Ved at sætte egenskaben ngProjectAs peger den div, hvor tagheaderen er placeret, på select="header", og den del af tagheaderen projiceres til det blå område:
<ng-content>Generer ikke indhold. Lav et eksperiment For at lave et eksperiment defineres først en demo-barn-komponentkomponent:
Demo-komponentkomponent til:
Så i demo-komponent cast demo-child-component:
På dette tidspunkt ser vi i konsollen, at demo-barn-komponent-initialiseringen er fuldført! Disse ord. Men når vi klikker på knappen for at skifte operationer, er demo-barn-komponent-initialiseringen fuldført! Den bliver ikke længere printet, hvilket betyder, at vores demo-barn-komponent kun instansieres én gang – aldrig ødelagt og genskabt.
Hvorfor sker det her?
Årsager til forekomst
<ng-content> Det "producerer" ikke indhold, det projicerer blot eksisterende indhold. Du kan tænke på det som ækvivalent med node.appendChild(el) eller $(node).append(el)-metoden i jQuery: med disse metoder bliver noden ikke klonet, den flyttes blot til sin nye placering. Derfor vil livscyklussen for det projicerede indhold være bundet til, hvor det er erklæret, ikke vist på stedet.
Dette forklarer også det tidligere spørgsmål fra princippet:Hvis der er flere på samme tid, hvordan vil det eksterne indhold så blive projiceret?
Denne adfærd udføres af to grunde: konsistens og ydeevne. Hvad "ønsket konsistens" betyder, at du som udvikler kan gætte din applikations adfærd ud fra dens kode. Lad os sige, at jeg skrev følgende kode:
Selvfølgelig vil demo-barn-komponent-komponenten blive instansieret én gang, men hvis vi nu bruger en komponent fra et tredjepartsbibliotek:
Hvis et tredjepartsbibliotek har kontrol over livscyklussen for en demo-barn-komponent, vil jeg ikke have nogen måde at vide, hvor mange gange den er blevet instansieret. Den eneste måde at gøre dette på er at kigge på koden fra tredjepartsbiblioteker for at forstå deres interne behandlingslogik. Betydningen af at knytte en komponents livscyklus til vores applikationskomponenter i stedet for wrappers er, at udviklere kan kontrollere, at tællere kun instansieres én gang, uden at kende den interne kode i tredjepartsbiblioteker.
Årsager til præstationer vigtigere. Da ng-content blot er et bevægeligt element, kan det udføres ved kompilering, ikke under kørsel, hvilket i høj grad reducerer arbejdsbyrden for selve applikationen.
Workaround
For at komponenten kan kontrollere instansieringen af de projicerede underkomponenter, kan vi gøre dette på to måder: ved at bruge <ng-template> elementer og ngTemplateOutlets omkring vores indhold, eller ved at bruge strukturdirektiver med "*"-syntaks. For enkelhedens skyld bruger vi Syntax i eksemplet <ng-template> .
Demo-komponentkomponent til:
Derefter inkluderer vi demo-child-komponent i ng-skabelonen:
På dette tidspunkt, når vi klikker på knappen for at skifte, vil konsollen printe udDemo-barn-komponent initialisering fuldført!Disse ord.
|