V Angularju je komponenta posebna direktiva, njena posebnost pa je, da ima svojo predlogo (html) in slog (css). Zato lahko uporaba komponent naredi našo kodo zelo ločeno, ponovno uporabno in enostavno razširljivo. Običajne komponente so definirane takole:
demo.component.ts:
demo.component.html:
demo.component.scss:
Ko se sklicujemo na komponento, se prikaže razčlenjena vsebina komponente:
Predpostavimo, da komponenta mora sprejeti zunanjo projicirano vsebino, kar pomeni, da komponenta na koncu predstavi več kot le to, kar definira. V tem trenutku je povabljen glavni junak tega člankang-vsebina。
Preprosta projekcija
Začnimo z najpreprostejšim, dodajte spremenjeni demo.component.html in demo.component.scss v demo.component.html, kot sledi:
demo.component.html:
demo.component.scss:
Zaradi učinka je barva ozadja v posodi namerno definirana kot oranžna.
Na tej točki lahko vsebino predvajamo od zunaj, ko se sklicujemo na komponento, zunanja vsebina pa se prikaže v oranžnem območju:
Ciljna projekcija
Če jih je več hkrati, kako se bo zunanja vsebina projicirala?
Najprej si poglejmo primer, za razlikovanje sem dodal modro območje, spremenjeno demo.component.html in demo.component.scss na naslednji način:
demo.component.html:
demo.component.scss:
Za referenco komponente:
Na tej točki bomo videli, da je zunanja vsebina projicirana na modro območje:
Seveda, če za modro območno številko dodate oranžno klicno številko, bo zunanja vsebina projicirana na oranžno območje:
Iz zgornjega primera lahko vidimo, da če obstaja tudi preprosta , potem bo zunanja vsebina projicirana v zadnjo predlogo komponente.
Torej, ko poznamo ta problem, se morda sprašujemo, ali lahko zunanjo vsebino projiciramo na ciljen način? Odgovor je očitno da.
Da se s tem spopadete, podprite enegaizbratiLastnosti, ki vam omogočajo, da določeno vsebino projicirate na določen prostor. Ta lastnost podpira CSS izbirnike (izbirnik oznak, izbirnik razredov, izbirnik atributov、... ) da se ujema s tem, kar želiš. Če na ng-vsebini ni nastavljen atribut izbire, bo prejel celotno vsebino ali vsebino, ki ne ustreza nobenemu drugemu elementu ng-vsebine.
Če pogledamo neposredno primer, sta spremenjena demo.component.html in demo.component.scss naslednja:
demo.component.html:
demo.component.scss:
Kot lahko vidite iz zgornje kode, bo modro območje prejelo del glave oznake, rdeče območje bo prejelo del diva z razredom "demo2", zeleno območje bo prejelo del diva z imenom lastnosti "demo3", oranžno območje pa bo prejelo preostalo zunanjo vsebino (začetek, I sem vsebina zunanje vdelave, konec).
Za referenco komponente:
Na tej točki bomo videli zunanjo vsebino, projicirano v določeno .
Razširitev znanja
ngProjectAs
Zdaj vemo, da lastnost select ng-content omogoča, da določite, da je zunanja vsebina projicirana v dano .
Za pravilno projiciranje vsebine na podlagi atributa select obstaja omejitev – ne glede na to, ali gre za glavo oznake, div z razredom "demo2" ali div z imenom lastnosti "demo3", so vse te oznake neposredna podvozla komponentne oznake.
Kaj bi se zgodilo, če ne bi bil neposredno podvozlišče? Preprosto spremenimo kodo, ki se sklicuje na demo-komponento, vstavimo glavo oznake v div in jo spremenimo takole:
Na tej točki vidimo, da del vsebine, ki je v obliki zavihke, ni več projiciran v modro območje, temveč v oranžno območje. Razlog je, da <ng-content select="header"></ng-content> ne more ujeti prejšnje glave oznake, zato se ta del vsebine projicira v <ng-content></ng-content> oranžno območje.
Za rešitev tega problema moramo uporabiti lastnost ngProjectAs, ki jo lahko uporabimo na katerem koli elementu. Podrobnosti so naslednje:
Z nastavitvijo lastnosti ngProjectAs div, kjer se nahaja glava oznake, kaže na select="header", del glave oznake pa se projicira na modro območje:
<ng-content>Ne "ustvarjajte" vsebine Naredi eksperiment Za izvedbo eksperimenta najprej definirajte komponento demo-otrok-komponenta:
Demo-komponenta za:
Nato v demo-komponenti cast demo-child-component:
Na tej točki v konzoli vidimo, da je inicializacija demo-child-component zaključena! Te besede. Ko pa kliknemo gumb za preklop operacij, je inicializacija demo-child-component zaključena! Ni več natisnjena, kar pomeni, da je naš demo-otroški komponent instanciran le enkrat – nikoli uničen in ponovno ustvarjen.
Zakaj se to dogaja?
Vzroki pojava
<ng-content> Ne "ustvarja" vsebine, ampak le projicira obstoječo vsebino. Lahko si ga predstavljate kot ekvivalent metodi node.appendChild(el) ali $(node).append(el) v jQuery: pri teh metodah vozlišče ni klonirano, ampak se preprosto premakne na novo lokacijo. Zato bo življenjski cikel projicirane vsebine vezan na mesto, kjer je razglašena, ne pa prikazan na mestu.
To prav tako pojasnjuje prejšnje vprašanje iz načela:Če jih je več hkrati, kako se bo zunanja vsebina projicirala?
To vedenje se izvaja iz dveh razlogov: doslednost in uspešnost. Kaj pomeni "želena konsistentnost", da lahko kot razvijalec ugibate obnašanje svoje aplikacije na podlagi njene kode. Recimo, da sem napisal naslednjo kodo:
Seveda bo demo-child-komponenta instancirana enkrat, a zdaj, če uporabimo komponento iz knjižnice tretje osebe:
Če ima knjižnica tretje osebe nadzor nad življenjskim ciklom demo-otroške komponente, ne bom mogel vedeti, kolikokrat je bila ustvarjena. Edini način za to je, da pogledate kodo knjižnic tretjih oseb, da razumete njihovo notranjo procesno logiko. Pomen vezanja življenjskega cikla komponente na naše aplikacijske komponente namesto na ovoje je, da lahko razvijalci nadzorujejo, da se števci instancirajo le enkrat, ne da bi poznali notranjo kodo knjižnic tretjih oseb.
Razlogi za uspešnostje pomembnejše. Ker je ng-vsebina le premikajoči se element, jo je mogoče izvajati med prevajanjem, ne med izvajanjem, kar močno zmanjša obremenitev dejanske aplikacije.
Rešitev
Da bi komponenta nadzorovala instanciranje projiciranih podkomponent, lahko to storimo na dva načina: z uporabo <ng-template> elementov in ngTemplateOutlets okoli naše vsebine ali z uporabo strukturnih direktiv s sintakso "*". Za enostavnost bomo v primeru uporabili sintakso <ng-template> .
Demo-komponenta za:
Nato vključimo demo-child-komponento v ng-template:
Ko kliknemo gumb za preklop, se konzola izpišeInicializacija demo-child-komponente zaključena!Te besede.
|