Hello!
Czas na kolejny art związany z routingiem. W tym artykule poznasz etapy routingu i pokażę praktyczny przykład ich zastosowania. Zaimplementujemy spinner, który będzie się pokazywał podczas przechodzenia między widokami.
Skorzystam z Plunkera, którego stworzyłem na potrzeby tego artykułu:
ANGULAR 2 – RESOLVE SERVICE
Plunker:
W powyższym przykładzie, stworzyłem Resolve Service, który dostarcza nam dane przed aktywacją routa. Fajnie, jeśli użytkownik widziałby spinner podczas ładowania danych do widoku. Celowo teraz opóźnię załadowanie danych z API w pliku app.module.ts:
InMemoryWebApiModule.forRoot(InMemoryDataService, { delay: 2500})
Dzięki temu będzie czas, aby zobaczyć spinner.
ROUTER EVENTS
W routingu rozróżniamy następujące typy eventów:
- NavigationStart
- RoutesRecognized
- NavigationEnd
- NavigationCancel
- NavigationError
- RouteConfigLoadStart (związane z lazy loading)
- RouteConfigLoadEnd (związane z lazy loading)
Nazwy eventów od 1 do 5 jasno określają etap na jakim znajduje się routing, natomiast eventów 6-7 nie będę pokrywać w tym artykule.
Stan routingu możemy obserwować w konsoli przeglądarki, poprzez włączenie enableTracing w odpowiednim module z routingiem, w następujący sposób:
@NgModule({
imports: [ RouterModule.forRoot(routes, { enableTracing: true }) ],
exports: [ RouterModule ]
})
export class AppRoutingModule {}
Dzięki temu podczas przechodzenia między widokami, będziesz otrzymywać odpowiednie logi:

Spójrzmy teraz na klasę Router:
Router docs
Klasa router posiada pole Events typu Observable<Event> … a jeśli widzimy Observable… to znaczy, że możemy się subskrybować i nasłuchiwać na dany event! Whoaa!
Zatem jeśli pojawi się Event NavigationStart, to chcemy pokazać spinner, a natomiast jak wyemituje się Event NavigationEnd, to z pewnością będzie to dobry moment, aby ukryć spinner.
Zatem teraz wykorzystam Router.events do pokazania spinnera. Przechodzę do app.component.ts i subskrybuję się do router.events:
export class AppComponent {
isLoading = true;
constructor(private router : Router) {
router.events.subscribe((routerEvent : Event) => {
this.checkEvent(routerEvent);
})
}
checkEvent(routerEvent : Event) : void {
if (routerEvent instanceof NavigationStart) {
this.isLoading = true;
}
else if (routerEvent instanceof NavigationEnd ||
routerEvent instanceof NavigationCancel ||
routerEvent instanceof NavigationError) {
this.isLoading = false;
}
}
}
Powyższy kod jest prosty i jasny. Obsłużyłem również NavigationCancel oraz NavigationError. W tych przypadkach chcę również ukryć spinner. Teraz w templatce głównego komponentu (app.component.html) dodajemy diva ze spinnerem:
<div class="loader" *ngIf="isLoading"></div>
<router-outlet></router-outlet>
Natomiast sam spinner, to już kwestia CSSa, możesz np. wykorzystać Key Frames do animacji. Jeśli chcesz sprawdzić kod spinnera z przykładu, przejdź do pliku styles.css.
Link do kodu ze spinnerem i eventami, klikamy na dowolnego usera z listy:
LIVE EXAMPLE
Polecam również ciekawy artykuł, jak wykorzystać Router Events do dynamicznych zmian tytułów:
https://toddmotto.com/dynamic-page-titles-angular-2-router-events
I właściwie w ten oto prosty sposób, dodaliśmy spinnera do naszej aplikacji ; )
——————————-
Chciałbym również podsumować konkurs, w którym można było wygrać wejściówkę na konferencję Frontend-Con:
http://wp.angular.love/2017/06/05/konferencja-frontend-con-2017/
Gratulacje dla Piotra Lewandowskiego z Gdańska, który uzbierał zawrotną sumę 37 lajków pod udostępnieniem posta;)!
Mam nadzieję, że będziesz się dobrze bawić i wrócisz pełny nowej wiedzy 🙂