I Angular er en komponent en spesiell direktiv, og dens spesielle egenskap er at den har sin egen mal (html) og stil (css). Derfor kan bruk av komponenter gjøre koden vår svært frakoblet, gjenbrukbar og lett utvidbar. De vanlige komponentene defineres som følger:
demo.component.ts:
demo.component.html:
demo.component.scss:
Når vi refererer til komponenten, gjengis det parsede innholdet i komponenten:
Anta at det er behov for at komponenten aksepterer eksternt projisert innhold, noe som betyr at komponenten ender opp med å presentere mer enn bare det den definerer. På dette tidspunktet er hovedpersonen i denne artikkelen invitertng-innhold。
Enkel projeksjon
La oss starte med det enkleste, legg til de modifiserte demo.component.html og demo.component.scss til demo.component.html, som følger:
demo.component.html:
demo.component.scss:
For effektens skyld er bakgrunnsfargen på beholderen bevisst definert som oransje.
På dette tidspunktet kan vi kaste innhold utenfra når vi refererer til komponenten, og det eksterne innholdet vises i det oransje området:
Målrettet projeksjon
Hvis det er flere samtidig, hvordan vil det eksterne innholdet bli projisert?
La oss se på et eksempel først, for å skille ut, la jeg til et blått område, den modifiserte demo.component.html og demo.component.scss som følger:
demo.component.html:
demo.component.scss:
For å referere komponenten:
På dette tidspunktet vil vi se at det eksterne innholdet projiseres til det blå området:
Selvfølgelig, hvis du setter det oransje retningsnummeret etter det blå, vil det eksterne innholdet bli projisert til det oransje området:
Så fra eksempelet ovenfor kan vi se at hvis det også finnes en enkel , så vil det eksterne innholdet bli projisert i den siste i komponentmalen.
Så med dette problemet kan vi lure på, kan vi projisere eksternt innhold på en målrettet måte? Svaret er åpenbart ja.
For å håndtere dette, støtt envelgeAttributter som lar deg projisere spesifikt innhold på et bestemt sted. Denne egenskapen støtter CSS-velgere (tag-velger, klassevelger, attributtvelger、... ) for å matche det du ønsker. Hvis ingen select-attributt er satt på ng-content, vil den motta hele innholdet, eller innholdet som ikke samsvarer med noe annet ng-content-element.
Ser man direkte på eksempelet, er de modifiserte demo.component.html og demo.component.scss som følger:
demo.component.html:
demo.component.scss:
Som du kan se fra koden ovenfor, vil det blå området motta delen av tagheaderen, det røde området vil motta delen av diven med klassen "demo2", det grønne området vil motta delen av diven med eiendomsnavnet "demo3", og det oransje området vil motta resten av det eksterne innholdet (start, jeg er innholdet i den eksterne embeden, slutt).
For å referere komponenten:
På dette punktet vil vi se det eksterne innholdet projisert inn i den angitte .
Utvid kunnskapen
ngProjectAs
Nå vet vi at select-egenskapen til ng-content lar deg spesifisere at eksternt innhold projiseres inn i en gitt .
For å korrekt projisere innhold basert på select-attributtet finnes det en begrensning – enten det er en tagheader, en div med klassen "demo2", eller en div med egenskapsnavnet "demo3", er disse taggene alle direkte undernoder av komponenttaggen.
Hva ville skjedd hvis det ikke var for å være en direkte subnode? La oss enkelt endre koden som refererer til demo-komponentkomponenten, legge tagheaderen i en div, og endre den som følger:
På dette tidspunktet ser vi at faneoverskriftsdelen av innholdet ikke lenger projiseres i det blå området, men i det oransje området. Årsaken er at <ng-content select="header"></ng-content> ikke kan matche forrige tag-header, så denne delen av innholdet projiseres til det <ng-content></ng-content> oransje området.
For å løse dette problemet må vi bruke egenskapen ngProjectAs, som kan brukes på hvilket som helst element. Detaljene er som følger:
Ved å sette egenskapen ngProjectAs, peker diven hvor tagheaderen er plassert til select="header", og delen av tagheaderen projiseres til det blå området:
<ng-content>Ikke «generer» innhold Gjør et eksperiment For å gjøre et eksperiment, definer først en demo-barn-komponentkomponent:
Demo-komponentkomponent til:
Deretter i demo-komponent kast demo-barn-komponent:
På dette tidspunktet ser vi i konsollen at initialiseringen av demo-barn-komponenten er fullført! Disse ordene. Men når vi klikker på knappen for å bytte operasjoner, er initialiseringen av demo-barnekomponenten fullført! Den er ikke lenger trykket, noe som betyr at vår demo-barn-komponentkomponent bare instansieres én gang – aldri ødelagt og gjenskapt.
Hvorfor skjer dette?
Årsaker til forekomsten
<ng-content> Det "produserer" ikke innhold, det projiserer bare eksisterende innhold. Du kan tenke på det som tilsvarende node.appendChild(el) eller $(node).append(el)-metoden i jQuery: med disse metodene blir ikke noden klonet, den flyttes bare til sin nye plassering. Derfor vil livssyklusen til projisert innhold være bundet til der det er erklært, ikke vist på stedet.
Dette forklarer også det forrige spørsmålet fra prinsippet:Hvis det er flere samtidig, hvordan vil det eksterne innholdet bli projisert?
Denne oppførselen gjøres av to grunner: konsistens og ytelse. Hva "ønsket konsistens" betyr at du som utvikler kan gjette applikasjonens oppførsel basert på koden. La oss si at jeg skrev følgende kode:
Selvfølgelig vil demo-barn-komponent-komponenten bli instansiert én gang, men nå hvis vi bruker en komponent fra et tredjepartsbibliotek:
Hvis et tredjepartsbibliotek har kontroll over livssyklusen til en demo-barn-komponent, vil jeg ikke ha noen måte å vite hvor mange ganger den har blitt instansiert. Den eneste måten å gjøre dette på er å se på koden til tredjepartsbiblioteker for å forstå deres interne prosesseringslogikk. Betydningen av å knytte livssyklusen til en komponent til våre applikasjonskomponenter i stedet for wrappere, er at utviklere kan kontrollere at tellere bare instansieres én gang, uten å kjenne den interne koden til tredjepartsbiblioteker.
Årsaker til ytelseer viktigere. Fordi ng-content bare er et bevegelig element, kan det gjøres ved kompilering, ikke under kjøring, noe som i stor grad reduserer arbeidsmengden til selve applikasjonen.
Løsningsløsning
For at komponenten skal kontrollere instansieringen av de projiserte underkomponentene, kan vi gjøre dette på to måter: ved å bruke <ng-template> elementer og ngTemplateOutlets rundt innholdet vårt, eller ved å bruke strukturdirektiver med "*"-syntaks. For enkelhets skyld bruker vi Syntax i eksempelet <ng-template> .
Demo-komponentkomponent til:
Deretter inkluderer vi demo-child-komponent i ng-template:
På dette tidspunktet, når vi trykker på knappen for å bytte, vil konsollen skrives utInitiering av demo-barn-komponent fullført!Disse ordene.
|