#Angular2 – Breadcrumbs, w końcu

Prawie od samego początku, odkąd zacząłem pracować nad frontendem, miałem problem z breadcrumbs. Breadcrumbs, czyli w tłumaczeniu na język polski okruszki chleba. Nazwa wzięła się z bajki Jaś i Małgosia braci Grimm. Chodziło o wyznaczenie drogi powrotnej przy pomocy okruszków chleba. Nawigacja breadcrumbs polega na tym samym, czyli na wyświetleniu ścieżki powrotnej do głównego widoku aplikacji.

Na początku w ogóle się tym nie przejmowałem i stwierdziłem, że jakoś tam wymyślę, jak to zrobić. Niedawno przeprowadzałem testy breadcrumbs na kodzie znalezionym w sieci. Tamten kod pobierał dane z reoutingu i wyświetlał je w odpowiednim formacie. Problem był taki, że korzystał on z zagnieżdżania się routingu. Żeby to działało, musiałbym przerobić spory fragment aplikacji i każdy zestaw komponentów, musiałby mieć swój główny komponent, który przekierowywałby do pozostałych komponentów.

Zajęłoby mi to trochę czas, którego już zbyt wiele nie zostało, więc postanowiłem, że odłożę to na później i coś wymyślę.

Wczoraj wieczorem postanowiłem się za to zabrać i zrobiłem to tym sposobem, o którym gdzieś tutaj pisałem, czyli przy pomocy usługi. Stworzyłem więc usługę breadcrumbs, przez którą każdy komponent może komunikować się z komponentem breadcrumbs. Komponent breadcrumbs obserwuje cały czas zmienną w usłudze i aktualizuje ją.

Dzięki temu prostemu rozwiązaniu, ścieżki przesyłam z każdego komponentu, w formie tablicy obiektów. Każdy taki obiekt, posiada swoją ścieżkę, wyświetlany tekst i posiada również parametr active, który mówi, czy w dany element można kliknąć, czy nie.

Tak wygląda kod usługi:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { Subject } from 'rxjs/Subject';
 
@Injectable()
export class BreadcrumbsService {
    private subject = new Subject();
 
    sendBreadcrumbs(breadcrumbs: any) {
        this.subject.next(breadcrumbs);
    }
 
    clearBreadcrumbs() {
        this.subject.next();
    }
 
    getBreadcrumbs(): Observable {
        return this.subject.asObservable();
    }
}

Jest tutaj parametr subject, który przechowuje treść i 3 metody. Pierwsza służy do ustawiania zawartości, druga do czyszczenia (ta nie jest mi potrzebna, ale została na wszelki wypadek), oraz metoda do pobierania zawartości parametru.

Tak wygląda kod TS komponentu breadcrumbs. Wstrzykujemy usługę breadcrumbs i subskrybujemy metodę getBreadcrumbs. Jeśli pojawi się jakaś zmiana, komponent się zaktualizuje.

import { Component, OnInit, OnDestroy } from "@angular/core";
import { Subscription } from 'rxjs/Subscription';

import { BreadcrumbsService } from '../../_services/breadcrumbs.service';

@Component({
 moduleId: module.id,
 selector: "breadcrumb",
 templateUrl: "breadcrumb.component.html"
})
export class BreadcrumbComponent implements OnInit, OnDestroy {

 breadcrumbs: any = [];
 subscription: Subscription;

 constructor(private breadcrumbsService: BreadcrumbsService) {
     this.subscription = this.breadcrumbsService.getBreadcrumbs()
         .subscribe(breadcrumbs => { 
             this.breadcrumbs = breadcrumbs; 
         });
 }

 ngOnInit() {

 }

 ngOnDestroy() {
 this.subscription.unsubscribe();
 }

}

A oto kod, który to wszystko wyświetla. Zwykła pętla i warunki, które ustalają, czy dany element jest aktywny, czy nie.

 

{{ item.text }}

</ng-container> </div> </div>

Żeby wpisać coś do breadcrumbs, w dowolnym komponencie wstrzykujemy usługę breadcrumbs i w metodzie ngOnInit, korzystając z metody setBreadcrumbs, wpisujemy odpowiednią tablicę z obiektami:

this.breadcrumbsService.sendBreadcrumbs([
    {'path': '/', 'text': 'Warsztat', 'active': true},
    {'path': '', 'text': 'Dokumenty', 'active': false}
]);

I to wszystko. Dzięki takiemu rozwiązaniu mogę w breadcrumbs wpisywać np. numer konkretnego dokumentu, czy nazwę klienta, przez co mam większą swobodę, niż w przypadku poprzedniego skryptu, który wymagał kilku sporych zmian w aplikacji.

Czas trwania konkursu powoli dobiega końca. Zostały już niecałe 2 tygodnie. Myślę, że z podstawową funkcjonalnością się wyrobię, ale mogę nie zdążyć, z wprowadzeniem samochodów zastępczych i raportów. Do raportów prawdopodobnie będzie mi wygodniej dopisać osobny kontroler w API, który pobierze mi z bazy odpowiednie dane i wyświetli je.

Teraz jeszcze zacząłem się zastanawiać, czy nie zmienić bazy danych, np. na MySQL albo inną bazę. Jeszcze się nad tym zastanowię.

Pozdrawiam!
MTK

Proudly powered by WordPress | Theme: Baskerville 2 by Anders Noren.

Up ↑