Sådan oprettes en genbrugsindikator til Angular-projekter

Genanvendelighed . Et ord, der har været i mit sind flere gange for nylig, mens jeg arbejdede på et Angular-projekt. Jeg har besluttet at oprette mine egne Angular-genanvendelige produkter og blogge om oplevelsen.

Så hvad er en lastningsindikator? Normalt er det en slags spinner med et overlay, som forhindrer brugerinteraktion. Brugergrænsefladen kan ikke klikkes, og fokus fanges. Derfor kan brugeren ikke mutere dataene eller applikationstilstanden ved et uheld ved at interagere med input bag overlayet.

Når indlæsningen stopper, fjernes overlayet med spinderen fra DOM, og det tidligere fokuserede element fokuseres igen.

Jeg startede med den logik, der ville udløse spinneren. Til det brugte jeg en simpel BehaviorSubject og to dekoratørfunktioner:

import {BehaviorSubject} from 'rxjs'; import {distinctUntilChanged} from 'rxjs/operators'; const indicatorSubject = new BehaviorSubject(false); export const isLoading$ = indicatorSubject.asObservable().pipe(distinctUntilChanged()); export function startLoadingIndicator(target: any, propertyKey: string | symbol, propertyDescriptor: PropertyDescriptor): any { const original = propertyDescriptor.value; propertyDescriptor.value = (...args) => { indicatorSubject.next(true); const result = original.call(target, ...args); return result; }; return propertyDescriptor; } export function stopLoadingIndicator(target: any, propertyKey: string, propertyDescriptor: PropertyDescriptor): any { const original = propertyDescriptor.value; propertyDescriptor.value = (...args) => { indicatorSubject.next(false); const result = original.call(target, ...args); return result; }; return propertyDescriptor; } 

På denne måde har vi ikke brug for en injicerbar service til at udløse eller stoppe spinderen. De to enkle dekoratørmetoder kalder bare .next () på vores BehaviorSubject. Variablen isLoading $ eksporteres som en observerbar.

Lad os bruge det i vores indlæsningsindikatorkomponent.

get isLoading$(): Observable { return isLoading$; }

Nu i din skabelon kan du bruge din isLoading $ getter med async-røret til at vise / skjule hele overlayet.

Som du kan se, trak jeg spinderen ud i sin egen komponent, og jeg har gjort flere andre ting. Jeg tilføjede nogle logik til fokusfangst og evnen til at konfigurere størrelsen og farven på spinneren ved hjælp af et InjectionToken.

import {LoadingIndicatorConfig} from './interfaces/loading-indicator.interfaces'; import {InjectionToken} from '@angular/core'; export const DEFAULT_CONFIG: LoadingIndicatorConfig = { size: 160, color: '#7B1FA2' }; export const LOADING_INDICATOR_CONFIG: InjectionToken = new InjectionToken('btp-li-conf'); 

At levere konfigurationsobjekter ved hjælp af InjectionToken er en god måde at give konfigurerbare egenskaber i konstruktøren.

 constructor(@Inject(LOADING_INDICATOR_CONFIG) private config: LoadingIndicatorConfig) { }

Nu er vi nødt til at samle alt sammen i en NgModule:

import {ModuleWithProviders, NgModule} from '@angular/core'; import {LoadingIndicatorComponent} from './loading-indicator/loading-indicator.component'; import {CommonModule} from '@angular/common'; import {SpinnerComponent} from './spinner/spinner.component'; import {DEFAULT_CONFIG, LOADING_INDICATOR_CONFIG} from './loading-indicator.config'; @NgModule({ declarations: [LoadingIndicatorComponent, SpinnerComponent], imports: [ CommonModule ], exports: [LoadingIndicatorComponent] }) export class LoadingIndicatorModule { static forRoot(): ModuleWithProviders { return { ngModule: LoadingIndicatorModule, providers: [{provide: LOADING_INDICATOR_CONFIG, useValue: DEFAULT_CONFIG}] }; } }

Efter at have bygget biblioteket og installeret det i en kantet applikation, bliver det meget let at udløse spinneren ved hjælp af de to dekoratørmetoder.

Først skal vi tilføje komponenten til det rette sted i DOM. Jeg lægger det normalt til appindgangskomponenten nederst i skabelonen.

Loading indicator

START LOADING

Som du kan se, kaldes triggerLoadingIndicator-metoden, når der klikkes på knappen. Denne metode er en dekoreret metode:

 @startLoadingIndicator triggerLoadingIndicator() { setTimeout(this.triggerLoadingIndicatorStop.bind(this), 500); } @stopLoadingIndicator triggerLoadingIndicatorStop() { console.log('stopped'); }

Og det er det. Selvfølgelig kunne man i en rigtig applikation bruge den til at dekorere anmodninger og deres respektive svarhåndterere. Et hurtigt tip: Dekorer også dine fejlhåndterere. :)

Mange tak for at læse dette blogindlæg. Hvis du vil prøve ovennævnte lib ud, kan du finde pakken og instruktioner til installation af den her.

Du kan også følge mig på Twitter eller GitHub.