От автора: вы когда-нибудь задавались вопросом, почему вы загружаете в Angular компоненты, а после этого вызывается API?
То, с чем вы могли встречаться — мы выводим загрузчик после отображения компонента, а также смотрим, скрыть ли или показать загрузчик страниц, или наш пользователь / клиент задает такой вопрос:
Почему мы отображаем загрузчик после загрузки страницы, не можем ли он показывать мои данные один раз. Посмотрите на этот сайт на WordPress, он загружает данные один раз.
Resolver в действии
Без Resolver, стандартный процесс
Обработка ошибок: Компонент загружен, вызывается загрузка данных из API, чтобы получить нужные данные для нашей страницы или компонента. Зачем переходить на страницу, когда данные, необходимые для использования страницы для пользователей, не загружаются?
Загрузчик: Вам нужно управлять переменной загрузчика, чтобы переключать представление при загрузке данных, если данные разбросаны по странице, вы используете все данные для переключения видимости каждого блока. Как насчет наличия загрузчика маршрутизатора SINGLE Navigation Event, и вы можете не беспокоиться о том, чтобы следить за тем, чтобы переменная отображала видимость?
Желательно предварительно получать данные с сервера, чтобы он был готов в тот момент, когда маршрут активирован. Это также позволяет обрабатывать ошибки до перехода к компоненту: https://angular.io/guide/router#resolve-guard
Если вы встречались с приведенными выше проблемами, вы можете продолжить чтение. То, что мы собираемся сделать — создать приведенное выше приложение, используя резольвер.
Создайте приложение Angular с помощью Angular cli
ng new resolver
Создайте маршруты
Создайте файл src/app/app.routes.ts и добавьте в него приведенный ниже код.
import { Routes } from '@angular/router'; import { RecordsComponent } from './records/records.component'; import { HomeComponent } from './home/home.component'; export const APP_ROUTES: Routes = [ { path: 'home', component: HomeComponent }, { path: '', redirectTo: 'home', pathMatch: 'full' }, { path: 'records/:with-error', component: RecordsComponent}, { path: '**', redirectTo: 'home' } ];
Здесь добавлен параметр маршрута with-error, информирующий, дает ли приложение сбой через значение true | false. Давайте создадим наши страницы / компоненты:
ng g c home -it -is --spec false ng g c records -is --spec false
Мы собираемся создать резольвер для обработки того, какую страницу возвращать в зависимости от того, возникла ли ошибка приложения или нет.
ng g s resolvers/recordComp --spec false
Откройте созданный выше файл службы, нам нужно реализовать интерфейс резольвера Angular.
import { Injectable } from '@angular/core'; import { IData } from '../interfaces/idata'; import { ActivatedRouteSnapshot, RouterStateSnapshot, Resolve } from '@angular/router'; import { MockHttpService } from '../services/mock-http.service'; import { Observable } from 'rxjs/Observable'; import 'rxjs/add/observable/forkJoin'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/catch'; import 'rxjs/add/observable/throw'; interface IReturn { records: IData[]; dynamicTitle: string; } @Injectable() export class RecordCompResolver implements Resolve<IReturn> { constructor(private _mockService: MockHttpService, private _ngAlert: NgAlertService) { } resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<IReturn> { const withError = route.params['with-error'] === 'true'; return Observable.forkJoin ([ this._mockService.dynamicTitle('resolver'), this._mockService.request(withError) ]) .map(results => ({ dynamicTitle: results[0], records : results[1] })) .catch(error => { this._ngAlert.push({ message: error.message, type: MessageType.error }); return Observable.throw(error); }); } }
Мы создали включаемую службу, резольвер — это просто реализация Resolve<T>, где T — ожидаемое возвращаемое значение, которое указано как интерфейс IReturn. Наш MockHttpService похож на провайдер api, в котором выполняются основные вызовы api к серверу и асинхронный возврат данных с сервера.
Наблюдение осуществляется из вышеупомянутого файла резольвера, для управлением состоянием загрузки приложения больше ничего не требуется. Как это связано с началом загрузки? Скоро мы рассмотрим это. Обработка ошибок до сих пор была очень простой, поскольку мы просто выполняли передачу ошибки с использованием встроенной службы NgAlert и выдавали ошибку маршрутизатору.
Теперь, когда мы создали резольвер, который возвращает данные, необходимые для records.component.ts, который может теперь предоставлять информацию, откройте компонент, и давайте извлечем данные из нашего резольвера, и, в зависимости от того, что мы получили, перейдем к стандартному отображению или управлению данными.
import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { IData } from '../interfaces/idata'; @Component({ selector: 'app-records', templateUrl: './records.component.html', styles: [] }) export class RecordsComponent implements OnInit { data: IData[] = []; dynamicTitle: string; constructor(private _route: ActivatedRoute) { } ngOnInit() { this.data = this._route.snapshot.data.pageData.records || []; this.dynamicTitle = this._route.snapshot.data.pageData.dynamicTitle; } }
Наш шаблон компонента может использовать data|dynamicTitle, как если бы данные были связаны с компонентом. Теперь давайте применим наш resolver к маршруту records.component.ts, добавив этот дополнительный ключ к объекту маршрута в app.routes.ts
... { path: 'records/:with-error', component: RecordsComponent, resolve: { pageData: RecordCompResolver } ...
Используя ключ resolv, мы можем добавить несколько резольверов для пары «ключ-значение», где ключ находится там, где будет храниться обработанное соответствующим резольвером значение, а затем мы можем извлечь его так:
this._route.snapshot.data[key] = ResolvedValue
Вернемся к вопросу, как это будет связано с началом загрузки? Все, что нам нужно — это подключиться к событию перехода Angular и работать с загрузчиком страницы. Чтобы получить дополнительную информацию о том, как это сделать, ознакомьтесь с приведенной ниже статьей: Загрузчик страницы Youtube с Angular 2+ события маршрутизатора.
Демо-версия, проиллюстрированная приведенными выше gif-изображениях доступна по ссылке: https://theo4u.github.io/Angular-resolvers/
Зависимости для данного приложения:
Bootstrap
ng2-slim-loading-bar
ngAlert
Автор: Theophilus Omoregbee
Источник: https://codeburst.io/
Редакция: Команда webformyself.