Angularis on komponent eridirektiiv ning selle eripäraks on oma mall (html) ja stiil (css). Seetõttu võib komponentide kasutamine muuta meie koodi väga lahutatuks, taaskasutatavaks ja kergesti laiendatavaks. Tavapärased komponendid on defineeritud järgmiselt:
demo.component.ts:
demo.component.html:
demo.component.scss:
Kui viidame komponendile, renderdatakse komponendi parsitud sisu:
Oletame, et komponent peab aktsepteerima väliselt projitseeritud sisu, mis tähendab, et komponent esitab lõpuks rohkem kui lihtsalt seda, mida ta määratleb. Sel ajal on selle artikli peategelane kutsutudng-sisu。
Lihtne projektsioon
Alustame lihtsaimast, lisame muudetud demo.component.html ja demo.component.scss demo.component.html-sse järgmiselt:
demo.component.html:
demo.component.scss:
Efekti huvides on konteineri taustavärv teadlikult määratletud oranžiks.
Sel hetkel saame sisu väljastpoolt saata, kui viidame komponendile, ning väline sisu kuvatakse oranžis alas:
Sihitud projektsioon
Kui neid on korraga mitu, kuidas projitseeritakse väline sisu?
Vaatame esmalt näidet, eristamiseks lisasin sinise ala, muudetud demo.component.html ja demo.component.scss järgmiselt:
demo.component.html:
demo.component.scss:
Komponendi viitamiseks:
Sel hetkel näeme, et väline sisu projitseeritakse sinisele alale:
Loomulikult, kui paned oranži suunakoodi sinise suunakoodi järel, projitseeritakse väline sisu oranžile alale:
Eelnevast näitest näeme, et kui on olemas ka lihtne , siis projitseeritakse väline sisu komponendimalli viimasesse ossa.
Seega, teades seda probleemi, võime mõelda, kas me suudame välist sisu sihipäraselt projitseerida? Vastus on ilmselgelt jah.
Selle lahendamiseks toeta ühtvalimaAtribuudid, mis võimaldavad projitseerida konkreetset sisu kindlasse kohta. See omadus toetab CSS valijaid (siltide valija, klassivalija, atribuudi valija、... ) et vastata sellele, mida sa tahad. Kui ng-sisule pole seatud select-atribuuti, saab see täissisu või sisu, mis ei vasta ühegi teise ng-sisu elemendile.
Vaadates otse näidet, on muudetud demo.component.html ja demo.component.scss järgmised:
demo.component.html:
demo.component.scss:
Nagu ülaltoodud koodist näha, saab sinine ala osa sildi päisest, punane ala div osa klassiga "demo2", roheline ala saab osa divist omadusnimega "demo3" ja oranž ala saab ülejäänud välise sisu (algus, ma olen välise manustamise sisu, lõpp).
Komponendi viitamiseks:
Sel hetkel näeme välist sisu projitseerituna määratud .
Laienda teadmisi
ngProjectAs
Nüüd teame, et ng-content select-omadus võimaldab määratleda, et väline sisu projitseeritakse antud objekti.
Sisu korrektseks projitseerimiseks select-atribuudi alusel on piirang – olgu selleks sildi päis, div klassiga "demo2" või div omadusnimega "demo3" – need sildid on kõik komponendi sildi otsesed alamsõlmed.
Mis juhtuks, kui see poleks otsene alamsõlm? Muudame lihtsalt koodi, mis viitab demo-komponendile, paneme sildi päise div-i ja muudame seda järgmiselt:
Sel hetkel näeme, et vahekaardi päise osa sisust ei projitseeru enam sinisesse alasse, vaid oranži alasse. Põhjus on selles, et <ng-content select="header"></ng-content> ei saa eelneva sildipäise sobitada, seega projitseeritakse see osa <ng-content></ng-content> sisust oranžile alale.
Selle probleemi lahendamiseks peame kasutama ngProjectAs omadust, mida saab rakendada igale elemendile. Üksikasjad on järgmised:
ngProjectAs omaduse määramisel osutab div, kus sildi päis asub, select="header" ja sildi päise osa projitseeritakse sinisele alale:
<ng-content>Ära "genereeri" sisu Tee katse Eksperimendi tegemiseks defineeri esmalt demo-laps-komponendi komponent:
demo-komponendi komponent:
Seejärel demo-komponendis cast demo-child-komponent:
Sel hetkel näeme konsoolis, et demo-laps-komponendi initsialiseerimine on lõpetatud! Need sõnad. Aga kui me vajutame nuppu, et operatsiooni vahetada, on demo-laps-komponendi initsialiseerimine lõpetatud! Seda enam ei trükita, mis tähendab, et meie demo-laps-komponendi komponent instantsitakse vaid korra – seda ei hävitata ega taasloota.
Miks see juhtub?
Esinemise põhjused
<ng-content> See ei "tooda" sisu, vaid projitseerib lihtsalt olemasolevat sisu. Seda võib mõelda kui ekvivalenti node.appendChild(el) või jQuery $(node).append(el) meetodile: nende meetoditega sõlme ei kloonita, vaid see lihtsalt viiakse uude asukohta. Seetõttu on projitseeritud sisu elutsükkel seotud selle deklareerimiskohaga, mitte ei kuvata kohapeal.
See selgitab ka eelmist printsiibi küsimust:Kui neid on korraga mitu, kuidas projitseeritakse väline sisu?
Seda käitumist tehakse kahel põhjusel: järjepidevus ja sooritus. Mis tähendab "soovitud järjepidevus" seda, et arendajana saad oma rakenduse käitumist aimata selle koodi põhjal. Oletame, et kirjutasin järgmise koodi:
Ilmselgelt instanseeritakse demo-laps-komponent üks kord, aga nüüd, kui kasutame kolmanda osapoole teegi komponenti:
Kui kolmanda osapoole raamatukogu kontrollib demo-laps-komponendi elutsüklit, siis mul ei ole võimalust teada, mitu korda seda on käivitatud. Ainus viis seda teha on vaadata kolmandate osapoolte teekide koodi, et mõista nende sisemist töötlemisloogikat. Komponendi elutsükli sidumine meie rakenduskomponentidega, mitte ümbristega, tähendab seda, et arendajad saavad kontrollida, et loendurid käivitatakse vaid korra, ilma et nad tunneksid kolmandate osapoolte raamatukogude sisemist koodi.
Soorituse põhjusedon olulisem. Kuna ng-sisu on lihtsalt liikuv element, saab seda teha kompileerimise ajal, mitte käitusajal, mis vähendab oluliselt tegeliku rakenduse töökoormust.
Lahendus
Selleks, et komponent saaks kontrollida projitseeritavate alamkomponentide instantsiseerimist, saame seda teha kahel viisil: kasutades <ng-template> elemente ja ngTemplateOutlete meie sisu ümber või struktuuridirektiive "*" süntaksiga. Lihtsuse huvides kasutame näites <ng-template> süntaksit .
demo-komponendi komponent:
Seejärel lisame ng-malli demo-child-komponenti:
Sel hetkel, kui vajutame nuppu, et vahetada, prindib konsool väljademo-lapse komponendi initsialiseerimine lõpetatud!Need sõnad.
|