Як створити багаторазовий індикатор завантаження для проектів Angular

Багаторазове використання . Слово, яке мені кілька разів приходило в голову нещодавно під час роботи над проектом Angular. Я вирішив створити власні Angular багаторазові та вести блог про досвід.

Отже, що саме таке індикатор завантаження? Зазвичай це спінер якогось типу з накладанням, який запобігає взаємодії користувачів. Інтерфейс користувача не можна натиснути, і фокус потрапив у пастку. Таким чином, користувач не може випадково мутувати дані або стан програми випадково, взаємодіючи із входами позаду накладання.

Після припинення навантаження накладка з блешнею знімається з DOM і попередньо сфокусований елемент знову фокусується.

Я розпочав з логіки, яка спрацьовує на спінер. Для цього я використав простий BehaviourSubject та дві функції декоратора:

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; } 

Таким чином, нам не потрібна ін’єкційна служба для спрацьовування або зупинки блешні. Два простих методи декоратора просто викликають .next () у нашому BehaviourSubject. Змінна $ isLoading експортується як спостережувана.

Давайте використаємо його в нашому компоненті індикатора завантаження.

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

Тепер всередині вашого шаблону ви можете використовувати ваш getLeading $ getter з асинхронною трубою, щоб показати / приховати все накладання.

Як бачите, я витягнув блешню у її власний компонент і зробив ще кілька речей. Я додав трохи логіки для захоплення фокусу та можливість налаштування розміру та кольору блешні за допомогою 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'); 

Забезпечення об’єктів конфігурації за допомогою InjectionToken - хороший спосіб забезпечити конфігурувані властивості в конструкторі.

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

Тепер ми повинні згрупувати все в 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}] }; } }

Після побудови бібліотеки та встановлення її у програму Angular запуск обертання стає надзвичайно простим за допомогою двох методів декоратора.

Спочатку нам потрібно додати компонент до належного місця в DOM. Зазвичай я розміщую його в компоненті програми, внизу шаблону.

Loading indicator

START LOADING

Як бачите, метод triggerLoadingIndicator викликається при натисканні кнопки. Цей метод є декорованим методом:

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

І це все. Звичайно, у реальному додатку його можна використовувати для оформлення запитів та відповідних обробників відповідей. Швидка порада: також прикрасьте свої обробники помилок. :)

Щиро дякую, що прочитали цю публікацію в блозі. Якщо ви хочете спробувати вищезгадану бібліотеку, ви можете знайти пакет та інструкції щодо її встановлення тут.

Ви також можете стежити за мною у Twitter або GitHub.