Angular Route Resolves in 10 Minutes

Päivitetty 13.07.2018: Laajamittainen koodin peruskorjaus uudempien konventioiden käyttämiseksi. Päivitetty Angular ja RxJS uusimpiin saatavilla oleviin versioihin, siirretty esimerkit StackBlitziin.

Tämän postauksen tavoitteena on havainnollistaa, miten Angularin reittiratkaisut toimivat 10 minuutissa, sekä tarjota esimerkkikoodi Stackblitziin. Jos olet jo perehtynyt AngularJS:n route resolveihin, suosittelen ohittamaan johdannon ja hyppäämään suoraan esimerkkisovellusosioon.

Sisällysluettelo

Intro
Esimerkkisovellus

  • Vaihe 1: Luo Resolver-luokka
  • Vaihe 2: Lisää Resolve-vahti reitittimeen
  • Vaihe 3: Lisää Resolve Guard reitittimeen
  • : Hae ratkaistut tiedot komponentin aktivoidusta reitistä

Huomautuksia & Vinkkejä

  • Välttää päällekkäisiä API-kutsuja
  • Multiple Resolves on samalle reitille
  • Passing Route Params to the Resolver

Loppuhuomautukset

Intro

Reitin ratkaisut eivät ole mitään muuta kuin tapa pre-noutaa komponentin tarvitsemat tiedot ennen sen alustamista. Yleensä nämä tiedot tulevat API:sta. Oletetaan, että sinulla on komponentti, jonka ainoa tehtävä on näyttää kaavio kuukauden päivittäisestä myynnistä; Ei ole mitään järkeä renderöidä näkymää tai ladata tätä komponenttia ennen kuin myyntitiedot ovat saatavilla. Itse asiassa monet kaaviokirjastot heittävät virheen, jos yrität alustaa kaaviota ennen kuin sille on toimitettu tietoja (ja niin tekee myös *ngFor). Voit tietysti kiertää tämän ongelman helposti piilottamalla html:n *ngIf:llä tai toimittamalla tilapäisesti tyhjän matriisin, kunnes tarvittavat tiedot on ladattu. Vaikka voit kuitenkin tulla toimeen ilman resoluutioita, niiden toteuttaminen auttaa tekemään koodista luettavampaa ja ylläpidettävämpää seuraavin tavoin:

  1. Välttää sekavan sekamelskan komponenttisi mallissa ja koodissa.
  2. selventämällä tarkoitustasi näyttämällä, mitkä tiedot on ladattava valmiiksi.

Näistä hyödyistä huolimatta monet sivustot välttävät resolvien käyttöä ja suosivat suurimman osan komponentin näyttämistä ja spinnerin näyttämistä niissä osioissa, joiden tietojen lataaminen on vielä kesken. Joissakin tapauksissa tämä lähestymistapa on UX-näkökulmasta toivottava, eikä resoluutiota pitäisi käyttää. Käytä harkintaa.

Esimerkkisovellus

Avaa esimerkkisovellus

Kuten näet, lähtökohtamme on hyvin yksinkertainen sovellus, jossa on kaksi reittiä – ”Etusivu” ja ”Uutiset”. Reittien välillä siirrytään klikkaamalla vastaavaa välilehteä. Aiomme lisätä resoluution, joka noutaa uutiset etukäteen API:sta ennen kuin News-komponentti latautuu. Tähän tarvitaan kolme vaihetta:

Vaihe 1: Luo resolver-luokka, joka tekee Http-kutsun noutaakseen tarvitsemamme tiedot etukäteen.

Luo uusi Typescript-tiedosto app-kansion sisälle ja nimeä se:

news-resolver.service.ts

Kopioi ja liitä sitten seuraavanlainen koodi uuteen tiedostoon (selitetään alla):

Kerrataanpa tarkemmin, mitä teimme yllä olevassa koodissa:

  • Lisäsimme ES6-import-lausekkeet tarvittavien moduulien tuomiseksi mukaan.

  • Loimme uuden TypeScript NewsResolver-luokan.

  • Lisäsimme Resolve-rajapinnan luokkaamme – tämä on OPTIIVINEN, mutta minkä tahansa luokan, jota aiomme käyttää resolverina, on toteutettava resolve-metodi, joten se on hyvä konventio.

  • Lisäsimme resolve()-metodin NewsResolver – tämä metodi vastaa tarvitsemiemme tietojen palauttamisesta. Metodin, joka palauttaa tiedot resoluutiovahdille, nimeäminen ”resoluutioksi” EI ole valinnaista – resoluutio ei toimisi, jos metodi olisi nimetty joksikin muuksi.

  • Jos huomasit, että yllä olevassa koodissa käytetään virheellisesti POST-pyyntöä GET:n sijasta, olet täysin oikeassa; Oikeassa sovelluksessa tämä olisi GET-pyyntö. Tässä olevissa esimerkeissä hyödynnetään , joka on sivusto, joka tarjoaa testattavia API-päätepisteitä.

Ennen kuin siirrymme eteenpäin, meidän on sisällytettävä juuri luomamme resolver-luokka reititysmoduuliimme. Siirry kohtaan app-routing.module.ts ja lisää NewsResolver providers-joukkoon. Tai jos vasta aloitat työskentelyn Angular 2:n kanssa, korvaa app-routing.module.ts:n sisältö yksinkertaisesti alla olevalla koodilla – muutokset on merkitty huomautuksilla:

Sen jälkeen olemme nyt määritelleet resolver-luokan. Seuraavissa vaiheissa lisäämme sen reittiimme.

Koodi Resolver-luokan lisäämisen jälkeen

Vaihe 2: Resolve-vartijan lisääminen reittiin.

Vaihda app-routing.module.ts:ssä seuraava koodirivi { path: 'news', component: NewsComponent } muotoon:

{ path: 'news', component: NewsComponent, resolve: { news: NewsResolver }}

Tämässä kohdassa lisäsimme vain äsken määrittelemämme resolve-vartijan reitillemme news. Tämä kertoo Angularille, että meidän on odotettava NewsResolver:n resolve()-metodin resolve() palauttavan datan ennen kuin näytämme NewsComponent:n.

On tärkeää huomauttaa, että news koodirivillä news: NewsResolver on se, minkä valitsin nimeksi sille, mitä tahansa dataa resolveri palauttaa. Voit nimetä sen miksi haluat.

Hieman sivuhuomautuksena – jos et tunne Angularin reittisuojia yleisesti ja haluat tietää lisää, dokumentaatio on täällä. Vartijoiden yksityiskohtiin meneminen ei kuulu tähän postaukseen, mutta sinun tulisi tietää, että on olemassa muitakin vartijoita kuin resolve, minkä vuoksi otin termin esille.

Koodi, johon on lisätty Resolve-vartija

Vaihe 3: Hae ratkaistut tiedot komponentin aktivoidusta reitistä.

Nyt kun meillä on resolver-luokka ja olemme lisänneet sen reittiimme, tiedot haetaan valmiiksi. Viimeinen vaihe on päästä käsiksi valmiiksi haettuihin tietoihin NewsComponent:ssä, joka sijaitsee app/news.component.ts:ssä. Siirry kyseiseen tiedostoon ja lisää seuraava ES6-moduuli:

import { ActivatedRoute } from '@angular/router';

Sitten tarjoa ActivatedRoute News-komponentin konstruktorissa lisäämällä seuraava koodi NewsComponent-luokan määritelmän yläosaan:

constructor(private route: ActivatedRoute) {}

Kuten tiedätte tai olette saattaneet jo arvata, ActivatedRoute:n avulla voimme päästä käsiksi tietoihin, jotka koskevat kulloinkin aktiivista reittiä, kuten reitin url-osoitteeseen, kyselyparametreihin jne. Se, mistä me tässä välitämme, on uutistieto, joka ladataan ActivatedRoute:een resoluutiovahdista. Saadaksesi resolvoidut uutistiedot reitistä, lisää ominaisuus, joka pitää sisällään uutistiedot:

public news: any;

ja hae sitten tiedot aktivoidusta reitistä, kun NewsComponent alustetaan:

 ngOnInit(): void { this.news = this.route.snapshot.data; }

Se on käytännössä siinä. Muuta uutiskomponentin mallia niin, että se näyttää uutiset reitin resoluutiosta poistamalla nykyinen sisältö:

<div>This is just a placeholder for now. News will go here. </div>

ja korvaamalla se seuraavalla:

Siitä pitäisi nyt tervehtiä viimeisimmällä uutisella ”Taivas on sininen”, kun napsautat uutiset-välilehteä.

Valmis koodi

Huomautuksia & Vinkkejä

– Ratkaisut voivat aiheuttaa turhia API-kutsuja: Resoluutio saa tietoja joka kerta, kun komponentti ladataan. Tämä johtaa usein tarpeettomiin API-kutsuihin, jotka vaikuttavat haitallisesti suorituskykyyn. Jos resoluutiosi saa tietoja, jotka eivät muutu usein, harkitse resoluution palauttamien tietojen kirjoittamista resolver-luokan ominaisuuteen ja yksinkertaisesti palauta tämä ominaisuus, jos se on jo asetettu. Esimerkissämme lisäisimme esimerkiksi aluksi määrittelemättömän news-ominaisuuden seuraavasti: public news: any = undefined; uutisresolveriimme. Sitten metodissa resolve() tarkistetaan, onko news-ominaisuus jo asetettu, ja palautetaan sen arvo ilman API-kutsua, jos se on asetettu, eli:

 resolve(): Observable<any> { if (this.news) { return this.getSavedNews(); } else { return this.getNewsFromApi() } }

Täydellinen koodiesimerkki alla. Jos observable-syntaksi vaikuttaa sinusta hieman epätavalliselta, se johtuu siitä, että käytän RxJS 6. Täällä on hyvä opetusohjelma RxJS:een hiljattain tehdyistä muutoksista, jos tarvitset kertausta.

Palauta tallennetut tiedot, jos ne on jo haettu API:sta

Voit luonnollisesti mennä pidemmälle ja asettaa aikajakson, jonka aikana tiedot ovat voimassa, paitsi tallentamalla tiedot, myös lisäämällä toisen timestamp-ominaisuuden ja tekemällä API-kutsun, jos tiedot ovat vanhempia kuin x.

– Aivan kuten AngularJS:ssä, voit käyttää useita resolveja samassa reitissä. Resoluutiokutsut tehdään rinnakkain ja komponentti latautuu vasta, kun kaikki kutsut palauttavat tietoja. Jos haluat käyttää useita resolveja, lisää ne yksinkertaisesti reittiin:

Tällöin ylimääräisiä resolve-tietoja voidaan käyttää reitin tilannekuvasta aivan kuten yhdellä resolvella:

 ngOnInit(): void { this.news = this.route.snapshot.data; this.alternativeNews = this.route.snapshot.data; }

Koodi useilla resolveilla

– Resolveri pääsee käsiksi reitin parametreihin. Oletetaan, että sinulla on komponentti, joka näyttää listan uutisjuttujen otsikoista. Kun juttua klikataan, avataan toinen komponentti, joka näyttää koko artikkelin. Ennen tuon komponentin lataamista on haettava etukäteen sen uutisjutun sisältö, jonka otsikkoa napsautettiin – tämä voidaan tehdä resolver-metodissa. Resolver-luokalla on pääsy ActivatedRoute-luokkaan, joten voimme saada klikatun jutun id:n:

 resolve(route: ActivatedRouteSnapshot) { let id: any = route.params); return this.getNewsStory(id); }

Tämä on melko itsestään selvää. Katso esimerkkinä uusi src/news-story-resolver.service.ts-tiedosto alla olevasta linkistä. Linkit uuteen komponenttiin lisättiin News-välilehdelle (news.component.ts).

Code With Parameterized Resolve

Vastaa

Sähköpostiosoitettasi ei julkaista.