Angular Route se vyřeší za 10 minut

Aktualizováno 13.7.2018: Rozsáhlá revize kódu s ohledem na novější konvence. Aktualizován Angular a RxJS na nejnovější dostupné verze, příklady přesunuty na StackBlitz.

Cílem tohoto příspěvku je ukázat, jak funguje Angular route resolves během 10 minut, spolu s poskytnutím ukázkového kódu na Stackblitz. Pokud již znáte route resolves z AngularJS, doporučuji přeskočit úvod a přejít rovnou na část s ukázkovou aplikací.

Obsah

Úvod
Vzorová aplikace

  • Krok 1: Vytvořte třídu resolveru
  • Krok 2: Přidejte do trasy strážce resolveru
  • Krok 3: Vytvořte třídu resolveru
  • : Získání vyřešených dat z aktivované trasy komponenty

Poznámky &Tipy

  • Vyhnutí se nadbytečným voláním API
  • Vícenásobné vyřešení na stejné trasy
  • Předávání parametrů trasy řešiteli

Závěrečné poznámky

Úvod

Rozřešení trasy není nic jiného než způsob, jak před-načtení dat, která komponenta potřebuje před svou inicializací. Obvykle tato data pocházejí z rozhraní API. Řekněme, že máte komponentu, jejíž jedinou úlohou je zobrazit graf denních tržeb za daný měsíc; Nemá smysl vykreslovat zobrazení nebo načítat tuto komponentu dříve, než budou k dispozici data o tržbách. Ve skutečnosti mnoho knihoven pro tvorbu grafů vyhodí chybu, pokud se pokusíte inicializovat graf před dodáním dat (a stejně tak i *ngFor). Tento problém lze samozřejmě snadno obejít skrytím html pomocí *ngIf nebo dočasným dodáním prázdného pole, dokud se nenačtou potřebná data. Nicméně, i když se můžete obejít bez resolvů, jejich implementace pomáhá učinit kód čitelnějším a udržovatelnějším tím, že:

  1. Eliminuje matoucí nepořádek v šabloně a kódu komponenty.
  2. Zpřehlednění vašeho záměru tím, že ukážete, která data musí být předem načtena.

I přes tyto výhody se mnoho webů vyhýbá používání resolvů ve prospěch zobrazení většiny komponenty a zobrazení spinneru v částech, pro které se data teprve načítají. V některých případech je tento přístup z hlediska UX žádoucí a resolve by se používat neměl. Postupujte podle vlastního uvážení.

Vzorová aplikace

Otevřít vzorovou aplikaci

Jak vidíte, naším výchozím bodem je velmi základní aplikace se dvěma trasami – „Domů“ a „Novinky“. Mezi jednotlivými trasami se pohybujete kliknutím na příslušnou záložku. Přidáme řešení pro předběžné načtení zpráv z rozhraní API před načtením komponenty Zprávy. To bude probíhat ve třech krocích:

Krok 1: Vytvoříme třídu resolver, která provede volání Http pro předběžné načtení potřebných dat.

Vytvořte nový soubor Typescript uvnitř složky app a pojmenujte jej:

news-resolver.service.ts

Poté do nového souboru zkopírujte a vložte následující kód (vysvětleno níže):

Podívejme se, co jsme udělali v kódu výše:

  • Přidali jsme příkazy ES6 import, abychom přivedli potřebné moduly.

  • Vytvořil novou třídu TypeScript NewsResolver.

  • Přidal do naší třídy rozhraní Resolve – to je VOLITELNÉ, ale každá třída, kterou plánujeme použít jako resolver, musí implementovat metodu resolve, takže je to dobrá konvence.

  • Přidal jsem do NewsResolver metodu resolve() – to je metoda zodpovědná za vrácení dat, která potřebujeme. Pojmenování metody, která vrací data pro strážce resolve, „resolve“ NENÍ volitelné – resolver by nefungoval, kdyby se metoda jmenovala jinak.

  • Pokud jste si všimli, že v kódu výše je nesprávně použit požadavek POST místo GET, máte naprostou pravdu; Ve skutečné aplikaci by to byl požadavek GET. Příklady zde využívají , což je stránka poskytující testovací koncové body API.

Než budeme pokračovat, musíme do našeho směrovacího modulu zahrnout třídu resolver, kterou jsme právě vytvořili. Přejděte na app-routing.module.ts a přidejte NewsResolver do pole providers. Nebo, pokud s Angular 2 teprve začínáte pracovat, jednoduše nahraďte obsah app-routing.module.ts následujícím kódem – změny jsou označeny poznámkami:

Pokud je to hotovo, máme nyní definovanou třídu resolver. V následujících krocích ji přidáme do naší trasy.

Kód po přidání třídy resolveru

Krok 2: Přidání strážce resolveru do trasy.

V kódu app-routing.module.ts změňte následující řádek kódu { path: 'news', component: NewsComponent } na:

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

Vše, co jsme zde udělali, bylo přidání právě definovaného strážce resolveru do naší trasy news. Tím Angularu řekneme, že musíme počkat, až metoda NewsResolver resolve() vrátí data, než zobrazíme NewsComponent.

Důležité je zdůraznit, že news v řádku kódu news: NewsResolver je to, co jsem se rozhodl pojmenovat pro jakákoli data vrácená resolverem. Můžete ho pojmenovat, jak chcete.

Ještě poznámka na okraj – pokud neznáte angulární route guards obecně a chtěli byste se dozvědět více, dokumentaci najdete zde. Zabývat se podrobnostmi o strážích je mimo rámec tohoto příspěvku, ale měli byste vědět, že kromě resolve jsou k dispozici i další stráže, což je důvod, proč jsem tento termín uvedl.

Kód s přidanou stráží Resolve

Krok 3: Získání resolvovaných dat z aktivované trasy komponenty.

Teď, když máme třídu resolver a přidali jsme ji do naší trasy, jsou data přednačítána. Posledním krokem je přístup k předfetovaným datům v naší NewsComponent umístěné v app/news.component.ts. Přejděte do tohoto souboru a přidejte následující modul ES6:

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

poté poskytněte ActivatedRoute v konstruktoru komponenty News přidáním následujícího kódu na začátek definice třídy NewsComponent:

constructor(private route: ActivatedRoute) {}

Jak víte nebo jste možná uhodli, ActivatedRoute nám umožňuje přistupovat k informacím o trase, která je právě aktivní, jako je url trasy, parametry dotazu atd. Nás zde zajímají údaje o novinkách, které se do ActivatedRoute načítají z hlídače resolve. Abychom získali data o vyřešených novinkách z trasy, přidáme vlastnost, která bude uchovávat data o novinkách:

public news: any;

a poté získáme data z aktivované trasy při inicializaci NewsComponent:

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

To je prakticky vše. Změňte šablonu komponenty news tak, aby zobrazovala zprávy z vyřešené trasy, a to tak, že odstraníte současný obsah:

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

a nahradíte jej:

Po kliknutí na kartu News by vás nyní měla přivítat nejnovější zpráva „Nebe je modré“.

Dokončený kód

Poznámky & Tipy

– Řešení může způsobit nadbytečná volání API: Resolve získává data při každém načtení komponenty. To často vede ke zbytečným voláním API, která nepříznivě ovlivňují výkon. Pokud váš resolve získává data, která se často nemění, zvažte zapsání dat vrácených resolve do vlastnosti ve třídě resolveru a prosté vrácení této vlastnosti, pokud již byla nastavena. V našem příkladu bychom například přidali původně nedefinovanou vlastnost news takto: public news: any = undefined; v našem resolveru zpráv. Poté v metodě resolve() zkontrolujeme, zda je vlastnost news již nastavena, a pokud ano, vrátíme její hodnotu bez volání API, tedy:

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

Následující příklad kódu je kompletní. Pokud se vám zdá syntaxe observable trochu neobvyklá, je to proto, že používám RxJS 6. Pokud si potřebujete osvěžit informace o změnách nedávno zavedených v RxJS, je zde dobrý návod.

Vrátit uložená data, pokud již byla načtena z API

Přirozeně můžete jít ještě dál a nastavit časové období, během kterého jsou data platná, a to tak, že data nejen uložíte, ale přidáte další vlastnost timestamp a provedete volání API, pokud jsou data starší než x.

– Stejně jako v AngularJS můžete na jedné trase použít více resolvů. Volání resolve jsou prováděna paralelně a komponenta se načte až poté, co všechna volání vrátí data. Chcete-li použít více resolvů, jednoduše je přidejte do trasy:

Poté lze ze snímku trasy přistupovat k dalším datům resolvů stejně jako u jednoho resolvu:

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

Kód s více resolvy

– Resolver má přístup k parametrům trasy. Řekněme, že máte komponentu, která zobrazuje seznam názvů zpráv. Po kliknutí na článek se otevře další komponenta, která zobrazí celý článek. Před načtením této komponenty musíme předem načíst obsah novinového článku, na jehož název bylo kliknuto – to lze provést v metodě resolve. Třída resolver má přístup k ActivatedRoute, takže můžeme získat id příběhu, na který bylo kliknuto:

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

Toto je celkem samozřejmé. Pro příklad se podívejte na nový soubor src/news-story-resolver.service.ts v odkazu níže. Odkazy na novou komponentu byly přidány na kartu Zprávy (news.component.ts).

Kód s parametrizovaným řešením

.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.