Transclusion, Injection and Procrastination

Muutama kuukausi sitten Kapunahele Wong ja minÀ mietimme ideoita puhe-ehdotuksista, jotka voisimme tehdÀ yhdessÀ. Se oli samoihin aikoihin, kun pÀÀtin tutustua Ivyyn, joten ajattelin, ettÀ se voisi sopia hyvin puheeksi. KapunahelellÀ oli kuitenkin erilainen ajatus:

Twitter, jossa tapahtuu hauskoja juttuja!

Kuulin Injector TreesistÀ ensimmÀistÀ kertaa, joten olin kiinnostunut. Kapunahele jakoi kanssani osan alustavasta tutkimuksestaan, ja sain tietÀÀ, ettÀ Angular Injectorin riippuvuuksien ratkaisualgoritmi ei ollutkaan niin yksinkertainen kuin olin aiemmin luullut.

SitÀ lÀhtien, kun NgModules otettiin kÀyttöön Angular 2.0:n 5. julkaisukandidaatissa.0, tarjosin palveluita vain moduulitasolla kÀyttÀen tuttua providers-ominaisuutta:

Vai Angular 6:sta lÀhtien kÀyttÀen Injectable-dekoraattorin providedIn-ominaisuutta:

Joko niin tai nÀin, ilmoitin aina palveluni moduulitasolla, enkÀ koskaan kiinnittÀnyt kovinkaan paljon huomiota muihin mahdollisuuksiin.

Enter Injector Trees 🌮

Kapunahele ja minÀ pÀÀtimme lÀhettÀÀ Injector Trees -keskustelumme Angular Connectiin. Useita kuukausia myöhemmin seuraava viesti rantautui postilaatikkooni:

Olimme ihan riemuissamme, puheemme hyvĂ€ksyttiin konferenssiin! 😊

Vietimme seuraavat viikot tutkimalla kaikkia piilossa olevia kulmia siitÀ, miten riippuvuusinjektio toimii Angularissa. TÀssÀ blogikirjoituksessa aion jakaa joitakin niistÀ kanssasi.

Aloitus yksinkertaisesti

Aloitamme yksinkertaisella Angular-sovelluksella. TĂ€ssĂ€ sovelluksessa on ”Kingdom”-palvelu ja yksi komponentti, joka injektoi Kingdomin ja nĂ€yttÀÀ Kingdomin nimen:

PÀÀdyin kÀyttÀmÀÀn esimerkissÀ lohikÀÀrmettÀ, koska rakastan kÀyttÀÀ niitÀ puolipisteiden sijasta koodissani.

TehdÀksemme asioista hieman mielenkiintoisempia, maustetaan sovelluksemme Unicorn-komponentilla. TÀmÀ komponentti tulostaa sen kuningaskunnan nimen, jossa se asuu:

MeillÀ on siis sovelluskomponentti ja sen sisÀllÀ yksisarvinen. Hienoa!

MitÀ tapahtuu nyt, kun muutamme AppComponent:n mÀÀritelmÀÀ ja annamme KingdomService:lle eri arvon?

Voimme tehdÀ tÀmÀn lisÀÀmÀllÀ komponentti-ilmoitukseen seuraavan rivin:

providers: 

Miten tÀmÀ vaikuttaa sovellukseemme? Kokeillaan ja katsotaan:

Kuten nÀet, arvo, jonka mÀÀrittelimme KingdomService:lle AppComponent:ssa, sai etusijan AppModulissamme mÀÀriteltyyn palveluun nÀhden (sitÀ ei mÀÀritelty suoraan siellÀ, vaan kÀyttÀen providedIn:aa, mutta lopputulos on sama).

Elementtipuu, modulipuu

Syy siihen, ettÀ nÀemme zombeja, on tapa, jolla riippuvuuksien resoluutio toimii Angularissa. Se etsii ensin komponenttien puun ja vasta sitten moduulien puun. Tarkastellaanpa UnicornComponent. Se injektoi instanssin KingdomService konstruktorinsa sisÀllÀ:

constructor(public kingdom: KingdomService) {}

Kun Angular luo tÀmÀn komponentin, se etsii ensin, onko samalle elementille kuin komponentti mÀÀritelty tarjoajia. NÀmÀ palveluntarjoajat on voitu rekisteröidÀ itse komponenttiin tai direktiivin avulla. TÀssÀ tapauksessa emme ole antaneet mitÀÀn arvoa KingdomService:lle UnicornComponent:n sisÀllÀ, eikÀ meillÀ ole mitÀÀn direktiivejÀ <app-unicorn>-elementissÀ.

Haku jatkuu sitten elementtipuussa ylöspÀin, menemÀllÀ AppComponent:een. TÀÀllÀ Angular havaitsee, ettÀ meillÀ on arvo KingdomService:lle, joten se syöttÀÀ tÀmÀn arvon ja lopettaa haun siihen. TÀssÀ tapauksessa Angular ei siis edes katsonut moduulipuuhun.

Angular on laiska!

Aivan kuten me ohjelmoijat, myös Angular on viivyttelijÀ. Se ei luo palveluiden instansseja, ellei sen todella tarvitse. Voit varmistaa tÀmÀn lisÀÀmÀllÀ KingdomService:n konstruktoriin console.log-lausekkeen (voit myös lisÀtÀ alert('I love marquees'), jos tunnet olosi nostalgiseksi tÀnÀÀn).

Voit nĂ€hdĂ€, ettĂ€ console.log-lauseketta ei koskaan suoriteta – koska Angular ei luo palvelua. Jos poistat providers:-ilmoituksen AppComponent:stĂ€ (tai siirrĂ€t sen UnicornComponent:een, jolloin se koskee vain yksisarvista ja sen lapsielementtejĂ€), sinun pitĂ€isi alkaa nĂ€hdĂ€ lokiviestiĂ€ konsolissasi.

Nyt Angularilla ei ole valinnanvaraa – se ei löydĂ€ KingdomService:aa etsiessÀÀn Elementtipuusta. NiinpĂ€ se menee ensin Module Injector Tree -puuhun, nĂ€kee, ettĂ€ annoimme palvelun siellĂ€, ja luo lopulta instanssin siitĂ€. NĂ€in ollen konstruktorin sisĂ€llĂ€ oleva koodi toimii, ja nĂ€et sinne laittamasi debug-tulosteen.

Direktiivien hyökkÀys!

Mainitsin, ettĂ€ myös direktiivit voivat antaa arvoja riippuvuusinjektiota varten. Kokeillaanpa sitĂ€. MÀÀrittelemme uuden appInvader-direktiivin, joka muuttaa valtakunnan arvon đŸ‘Ÿ:ksi.
Miksi? Koska ne olivat niin ihania VR + Angular -puheessa, jonka Alex Castillo ja minÀ pidimme ng-confissa.

Sitten lisÀÀmme toisen <app-unicorn>-elementin ja sovellamme siihen uutta appInvader-direktiiviÀ:

Odotetusti uusi yksisarvinen asuu đŸ‘Ÿ:n kingdomissa. TĂ€mĂ€ johtuu siitĂ€, ettĂ€ direktiivi antoi arvon KingdomService. Ja kuten edellĂ€ selitettiin, Angular aloittaa haun nykyisestĂ€ elementistĂ€, tarkastelee komponenttia ja kaikkia direktiivejĂ€, ja vasta jos se ei löydĂ€ pyydettyĂ€ arvoa sieltĂ€, se jatkaa etenemistĂ€ elementtipuussa ylöspĂ€in (ja sitten moduuleissa).

Katsotaanpa jotain hieman monimutkaisempaa:

SisÀltöÀ projisoivan metsÀn lisÀÀminen sovellukseen!

LisÀÀmme sovellukseemme uuden Forest-komponentin ja laitamme osan yksisarvisista tÀmÀn metsÀn sisÀlle, koska siellÀ yksisarviset asuvat (joku satunnainen kaveri sanoi noin quorassa, joten sen tÀytyy olla totta).

MetsĂ€-komponentti on yksinkertaisesti sĂ€iliö, joka kĂ€yttÀÀ sisĂ€llön projisointia nĂ€yttÀÀkseen lapsensa vihreĂ€n ”metsĂ€isen” taustan pÀÀllĂ€:

NÀemme siis AppForest-komponentin elementit ruohotaustalla, ja sen jÀlkeen kaiken projisoidun sisÀllön kirkkaan vihreÀn taustan pÀÀllÀ. Ja koska annoimme sovelluskomponenttimme sisÀllÀ arvon KingdomService, kaikki sen sisÀllÀ oleva perii sen (paitsi yksi yksisarvinen, jolla on appInvader-direktiivi).

Mutta mitĂ€ tapahtuu, jos annamme uuden arvon KingdomService:lle ForestComponent:n sisĂ€llĂ€? Saako projisoitu sisĂ€ltö (joka mÀÀriteltiin mallissa AppComponent) myös tĂ€mĂ€n uuden arvon valtakunnalle? Vai pysyykö se edelleen 🧟 valtakunnassa? Osaatko arvata?

SitĂ€ kutsuttiin ennen Transclusioniksi. Nyt sitĂ€ kutsutaan ”sisĂ€llön projisoinniksi”. Kuva: ng-conf

MetsÀn velho

LisÀÀmme edelliseen esimerkkiin yhden rivin, joka antaa 🧙-kuningaskunnan ForestComponent:

providers: 

Ja tÀmÀ on lopputulos:

Nyt tĂ€mĂ€ on mielenkiintoista – nĂ€emme metsĂ€n sisĂ€ltĂ€ sekoituksen kuningaskuntia! Itse metsĂ€elementti asuu 🧙-kuningaskunnassa, mutta projisoidulla sisĂ€llöllĂ€ nĂ€yttÀÀ olevan jakautunut persoonallisuus: yksisarviset kuuluvat myös 🧙-kuningaskuntaan, mutta niiden ylĂ€puolella oleva teksti osoittaa 🧟-kuningaskuntaa…

MÀÀrittelimme sekĂ€ nĂ€mĂ€ yksisarviset ettĂ€ tekstin samassa paikassa, app.component.html-mallin riveillĂ€ 12-15. Olennaista on kuitenkin se paikka, jossa itse komponentti on luotu DOM:ssa. Teksti rivillĂ€ 12 on itse asiassa sama kuin mitĂ€ teemme rivillĂ€ 4 – luemme saman AppComponent-instanssin kingdom-ominaisuutta. TĂ€mĂ€n komponentin DOM-elementti on itse asiassa <app-forest> DOM-elementin esi-isĂ€. Joten kun tĂ€mĂ€ AppComponent-instanssi luotiin, siihen injektoitiin 🧟-kuningaskunta.

Kaksi <app-unicorn>-elementtiĂ€ ovat kuitenkin <app-forest>-DOM-elementtien sisĂ€llĂ€, joten kun niiden UnicornComponents-instanssit luodaan, angular itse asiassa menee DOM:iin ylöspĂ€in ja nĂ€kee arvon, jonka annoimme KingdomService-ominaisuudelle ForestComponent:n sisĂ€puolella, ja nĂ€in ollen nĂ€mĂ€ yksisarviset injektoituvat 🧙-kuningaskunnalla.

Voit saavuttaa erilaisen kĂ€yttĂ€ytymisen, jos muutat providers:n viewProviders:ksi, kun mÀÀrittelet ForestComponent:n. Voit oppia lisÀÀ View Providersista tÀÀltĂ€, ja tutustu myös tĂ€hĂ€n koodiesimerkkiin, jossa muutin ForestComponent kĂ€yttĂ€mÀÀn View Providersia, joten nyt myös metsĂ€n sisĂ€llĂ€ olevat yksisarviset injektoidaan 🧟-kuningaskunnalla. Kiitos Lars Gyrup Brink Nielsenille, joka huomautti minulle tĂ€stĂ€!

siirsin Kromin T-Rexin tÀhÀn blogikirjoitukseen

Jatkakaa tutkimista!

Toivottavasti opit juuri jotain uutta Angularin Dependency Injection -jĂ€rjestelmĂ€stĂ€. TĂ€mĂ€ on vain yksi niistĂ€ asioista, joihin Kapunahele ja minĂ€ tutustuimme valmistellessamme puhettamme AngularConnectiin. On paljon muutakin – olet tervetullut tutkimaan lisÀÀ, ja jaamme myös diat ja linkin videoon puheen jĂ€lkeen. Ai niin, ja luvassa on myös live-koodausta. SiitĂ€ tulee hauskaa!

Jos haluat oppia lisÀÀ Angular Injectorin yksityiskohdista, tÀssÀ on muutama artikkeli, joita pidin erittÀin hyödyllisinÀ:

  • MitĂ€ olet aina halunnut tietÀÀ Angular Dependency Injectionista
  • A curious case of the @Host decorator and Element Injectors in Angular
  • Hierarchical Dependency Injectors (Angular Docs)

Ja jos osallistut AngularConnectiin, olet tervetullut tervehtimÀÀn!

Vastaa

SÀhköpostiosoitettasi ei julkaista.