Angularin reittiresolverien ymmärtäminen

winding-road-between-forest

Todellisen sovelluksen kehittäminen, jossa on useita kutsuja palvelimelle, voi olla täynnä virheitä. Jos olet täällä, se tarkoittaa, että olet kamppaillut API-kutsujen viiveen kanssa. Nämä viiveet saattavat aiheuttaa negatiivista UX:ää. Tänään aiomme ymmärtää Route Resolverit Angular 8:ssa. Voimme tehdä useita eri asioita käyttäjäkokemuksen parantamiseksi, kuten näyttää edistymisindikaattorin. Jotta pysytään aiheessa, katsotaan mitä Route Resolver on ja mitä voimme saavuttaa sen avulla.

Mikä on Angular Route Resolver?

Resolver on luokka, joka toteuttaa Angular Routerin Resolve-rajapinnan. Itse asiassa Resolver on palvelu, jonka on oltava juurimoduulissa. Periaatteessa Resolver toimii kuin middleware, joka voidaan suorittaa ennen komponentin lataamista.

Saatat myös pitää siitä: Angular Resolverit.

Miksi käyttää reittiresolvereita Angularissa?

Koska selitämme, miten resolveria voidaan käyttää Angularissa, ajatellaanpa skenaariota, jossa käytät *ngIf="some condition" ja logiikkasi perustuu array:n pituuteen, jota manipuloidaan API-kutsun valmistuttua. Saatat esimerkiksi haluta näyttää komponentissa tämän matriisin kohteet, jotka on juuri haettu järjestämättömänä listana.

<ul><li *ngFor="let item of items">{{item.description}}</li></ul>

Tässä tilanteessa saatat joutua ongelmaan, koska tietosi tulevat esiin vasta, kun komponentti on valmis. Joukon kohteita ei ole vielä oikeasti olemassa. Tässä kohtaa Route Resolver tulee tarpeeseen. Angularin Route Resolver -luokka hakee tietosi ennen kuin komponentti on valmis. Ehdolliset lausekkeesi toimivat sujuvasti Resolverin avulla.

Resolve-rajapinta

Ennen kuin alamme toteuttaa reittiresolveria, katsotaan ensin, miltä Resolve-rajapinta näyttää.

export interface Resolve<T> { resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<T> | Promise<T> | T { return 'Data resolved here...' }}

Jos haluat luoda reittiresolverin, sinun täytyy luoda uusi luokka, joka toteuttaa edellä mainitun rajapinnan. Tämä rajapinta tarjoaa meille resolve-funktion, jolla saat kaksi parametria, jos tarvitset niitä. Ensimmäinen on reitti, jonka tyyppi on ActivatedRouteSnapshot, ja toinen on tila, jonka tyyppi on RouterStateSnapshot. Tästä voit tehdä API-kutsun, jolla saat tarvitsemasi tiedot ennen komponentin lataamista.

Reittiparametrin kautta saat reittiparametrit, joita voidaan käyttää API-kutsussa. resolve-metodi voi palauttaa Observable:n, lupauksen tai vain mukautetun tyypin.

Huomaa: On tärkeää mainita, että tämän metodin kautta palautetaan vain ratkaistut tiedot.

Tämä on virhe, jonka monet tekevät käyttäessään resolvereita ensimmäistä kertaa! Sinun on siis täydennettävä ne ennen kuin lähetät ne reitittimeen.

Tietojen lähettäminen reitittimeen resolverin kautta

Näytän sinulle, mitä tarkoitan yllä olevassa kappaleessa. Oletetaan, että sinulla on metodi, joka palauttaa observable:

items: any = ;getData(): Observable<any> { const observable = Observable.create(observer => { observer.next(this.items) }); return observable;}

Nyt näet, että tilaus, joka meillä on, ei koskaan osu. Tämä johtuu siitä, että et lähetä dataa oikein. Et ole suorittanut tilausta loppuun. Korjataksesi tuon virheen, sinun täytyy viimeistellä tilaus lisäämällä yksi koodirivi lisää.

observer.complete();

Jos palautat lupauksen, sinun täytyy ratkaista se, ennen kuin lähetät datan reitittimelle.

Reitin ratkaisijan toteuttaminen

Kun olemme saaneet valmiiksi perusasioihin liittyvän selityksen ja sen, miksi ja miten reitinratkaisijaa käytetään, aletaan toteuttamaan sitä. Tässä lyhyessä esimerkissä oletan, että tunnet Angularin CLI-komennot ja uuden projektin luomisen, joten esittelen vain pakollisen koodin. Löydät demoprojektin artikkelin lopussa olevan GitHub-arkiston kautta.

Tässä esimerkissä käytän jsonplaceholderia väärennettynä API-rajapintana käyttäjätietojen noutamiseen, jotta voin demonstroida API-kutsuja reittiresolverien avulla.

Aluksi tarvitsemme palvelun, joka hakee käyttäjätiedot puolestamme. Tässä palvelussa meillä on funktio nimeltä getUsers(), joka palauttaa observable:n.

@Injectable({providedIn: 'root'})export class FakeApiService { constructor(private http: HttpClient) { } private usersEndpoint = "https://jsonplaceholder.typicode.com/users"; getUsers(): Observable<any> { // We do not subscribe here! We let the resolver take care of that... return this.http.get(this.usersEndpoint); }}

On tärkeää, ettei funktiota getUsers tilata. UserResolver-niminen reitittimen resolveri hoitaa tämän puolestasi. Seuraavaksi luodaan uusi palvelu nimeltä UserResolver, joka toteuttaa reitittimen Resolve-rajapinnan resolve-funktion.

@Injectable({providedIn: 'root'})export class UserResolverService implements Resolve<any> { constructor(private fakeApi: FakeApiService) { } resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { return this.fakeApi.getUsers().pipe( catchError((error) => { return empty(); }); ); }}

Tämä palvelu, UserResolver, tilaa automaattisesti getUsers observablea ja toimittaa reitittimelle haetut tiedot. Jos dataa noudettaessa tapahtuu virhe, voit lähettää tyhjän observablen, jolloin reititin ei jatka reititystä.

Navigointi lopetetaan tässä vaiheessa. Viimeinen vaihe on luoda komponentti, jota kutsutaan, kun käyttäjä siirtyy /users-reitille. Tyypillisesti ilman Resolveria sinun on haettava tiedot komponentin ngOnInit-koukulla ja käsiteltävä virheet, jotka johtuvat siitä, että ’tietoja ei ole’ on olemassa. Käyttäjän komponentti on yksinkertainen. Se vain hakee käyttäjän tiedot ActivatedRoute:sta ja näyttää ne järjestämättömänä listana.

Käyttäjän komponentin luomisen jälkeen sinun on määriteltävä reitit ja kerrottava reitittimelle, että se käyttää resolveria ( UserResolver). Tämä voidaan toteuttaa seuraavalla koodilla app-routing.modulte.ts:een.

const routes: Routes = ;@NgModule({ imports: , exports: })export class AppRoutingModule { }

Sinun täytyy asettaa resol-ominaisuus käyttäjän reitittimeen ja ilmoittaa UserResolver. Tiedot siirretään objektiin, jolla on ominaisuus nimeltä users. Tämän jälkeen olet melkein valmis. On vain yksi asia, joka sinun täytyy tehdä. Sinun täytyy saada haetut tiedot users-komponenttiin ActivatedRoute:n kautta seuraavalla koodilla:

constructor(private activatedRoute: ActivatedRoute) { }users: any;ngOnInit() { this.activatedRoute.data.subscribe((data: { users: any }) => { this.users = data.users; });}

Sitten voit vain näyttää ne HTML:ssä ilman *ngIf-lausekkeita ( *ngIf="users && users.length > 0 ), koska tiedot ovat siellä jo ennen komponentin lataamista.

<h2>Fetched Users:</h2><ul><li *ngFor="let user of users">{{ user.name }}</li></ul>

Yhteenveto

Lopettaakseni tämän Route Resolvereita käsittelevän artikkelin, haluaisin vielä kerran korostaa niiden tarjoamia etuja. Ensinnäkin vältämme ärsyttävät tarkistukset, jotka on tehtävä HTML-tasolla, joten meillä ei ole ongelmia ennen kuin datamme on vastaanotettu. Toiseksi niiden ansiosta voimme keskittyä enemmän käyttäjäkokemukseen, koska voimme lopettaa navigoinnin, jos noutamisen aikana tapahtuu tietovirhe, ilman että meidän tarvitsee ladata esikatselukomponenttia. Voimme myös tehdä enemmän ennen navigoinnin loppuunsaattamista, kuten liittää lisää logiikkaa tai kartoittaa dataa ennen ladatun komponentin käyttämistä.

Demokoodi on saatavilla GitHubissa.

Lisälukemista

  • Angular Tutorial: Angular 7 ja RESTEasy Framework.
  • Angular 5 -sovelluksen rakentaminen vaihe vaiheelta.
  • Angular 7 + Spring Boot -sovellus: Hello World Example.

Jätä kommentti