Angular - resolver czyli ładowanie zanim jeszcze na dobre wlazłeś do komponentu

Stronę tą wyświetlono już: 78 razy

Drogi czytelniku droga czytelniczko! Wybacz mi tę spouchwałość, ale jeżeli masz problem z załadowaniem danych do komponentu, który został podpięty do z góry określonej ścieżki routingu to mam rozwiązanie twoich bolączek! A rozwiązanie to zwie się resolver! Albowiem składa się tak wspaniale, że do danej ścieżki można podpiąć specjalną klasę resolvera, która załaduje wszystko co ci tylko przyjdzie do tej programistycznej głowy zanim w ogóle wejdziesz do komponentu. Czyniąc długą historię krótką oto przykład takiej klasy resolvera będącego tak naprawdę serwisem implementującym interfejs Resolve wymuszający obsługę jednej metody o jakże wymownej nazwie resolve:

Listing 1
  1. import { Injectable } from '@angular/core';
  2. import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
  3. import { of, Observable } from 'rxjs';
  4. import { FirstContactService } from 'src/app/submodule/first-contact.service';
  5. @Injectable({
  6. providedIn: 'root'
  7. })
  8. export class BooksResolverService implements Resolve<any> {
  9. constructor(
  10. private firstContactService: FirstContactService
  11. ) { }
  12. resolve(route: ActivatedRouteSnapshot, rstate: RouterStateSnapshot): Observable<any> {
  13. return this.firstContactService.getBooks();
  14. }
  15. }

W powyższym przykładzie wykorzystałem serwis opisywany na stronie Programowanie → Angular - podstawy → Angular - komunikacja z serwerem za pomocą HttpClient. Teraz konieczne jest podpięcie tej klasy do danej ścieżki. Oto przykład jak to uczyniłem w pliku app-routing.module.ts:

Listing 2
  1. path: 'books',
  2. component: BooksListComponent,
  3. resolve: {
  4. books: BooksResolverService
  5. }

Ale to jeszcze nie koniec, teraz trzeba jeszcze w konstruktorze komponentu BooksListComponent obsłużyć ładowanie danych:

Listing 3
  1. constructor( private act: ActivatedRoute) {
  2. this.act.data.subscribe(value => {
  3. console.log('Some extra data:', value);
  4. });
  5. }

Po wejściu na tą ścieżkę oczom twym w konsoli przeglądarki powinny ukazać się następujące informacje:

Some extra data: 
{...}
books: (2) [...]
0: Object { id: "1", title: "Rio Anaconda", author: "Wojciech Cejrowski" }
1: Object { id: "2", title: "Pan Tadeusz", author: "Adam Mickiewicz" }
length: 2

Możliwe jest również użycie wielu resolverów w następujący sposób:

Listing 4
  1. path: 'books',
  2. component: BooksListComponent,
  3. resolve: {
  4. books: BooksResolverService,
  5. anotherResolver: AnotherResolver // podpięcie kolejnego resolvera
  6. }

Komentarze