В нашей последней части этой серии мы узнали некоторые полезные вещи в Angular, в том числе: совершение звонков, функциональные модули и т. д. См. статью здесь.
В сегодняшней серии мы углубимся в резольверы. Если вы хорошо помните, вы помните, что иногда Angular маршрутизирует быстрее, чем мы можем получить данные с нашего сервера, что дает нам ошибку о том, что данные не определены. Есть отличные новости, у Angular есть способ решить эту проблему, и он использует распознаватели.
Резолверы. Резолверы — это способ приостановить загрузку компонента до тех пор, пока необходимые данные не будут отправлены клиенту. Он использует активированный маршрут Angular.
Посмотрим, как это работает
К сожалению, Angular не генерирует для нас файл резолвера, нам пришлось бы делать это вручную.
Из базы кода предыдущей серии создайте файл data.ressolvers.ts в каталоге src/app/user. и добавляем туда следующий кусок кода:
import { Injectable } from '@angular/core'; import { empty} from 'rxjs' import { Resolve } from '@angular/router'; import { catchError } from 'rxjs/operators'; import { ActivatedRouteSnapshot } from '@angular/router'; import {UserService} from './user.service' @Injectable() export class GetUsers implements Resolve<any> { constructor(private data:UserService) {} resolve(){ return this.data.getUser().pipe(catchError((err)=>{ return empty(); })) }}
Это просто создает новый класс GetUsers, реализующий Resolve. Обратите внимание, что мы также импортируем UserService и возвращаем полученное от него значение. Если есть ошибка, он не вернет ни один компонент. Следующим шагом мы должны сообщить нашему модулю, что этот преобразователь существует.
Импортируйте класс распознавателя в модуль и добавьте его к своим провайдерам.
import {GetUsers} from './data.resolvers' providers: [GetUsers]
Наконец, мы добавляем его в нашу маршрутизацию, чтобы убедиться, что условия распознавателей выполнены до того, как маршрутизация будет выполнена. Импортируйте его в свой файл маршрутизации пользователей и измените маршрут, где вы получаете список пользователей как таковой:
import {GetUsers} from './data.resolvers' { path:'user', component:UserComponent, resolve:{userInfo:GetUsers} }
Это разрешит список пользователей на этом маршруте с помощью моментального снимка userInfo. Давайте теперь посмотрим, как мы получаем эти данные в нашем компоненте.
В нашем пользовательском компоненте, где мы получили список всех пользователей, добавьте следующий фрагмент кода:
import { ActivatedRoute } from '@angular/router'; constructor(private router:ActivatedRoute) { } list:any ngOnInit() { this.list=this.router.snapshot.data['userInfo'] }
Обратите внимание, что нам не нужно подписываться на нашу службу при инициализации, мы просто получаем данные из активированного снимка маршрута.
Давайте теперь реализуем преобразователи для получения пользователя по идентификатору.
Как и раньше, перейдите в файл преобразователя и добавьте следующий фрагмент кода:
@Injectable() export class GetUserId implements Resolve<any> { constructor(private data:UserService) {} resolve(route: ActivatedRouteSnapshot){ return this.data.getProfile(route.paramMap.get('id')).pipe(catchError((err)=>{ return empty(); })) } }
Обратите внимание, что это немного отличается от класса распознавателя ранее, потому что в этом случае мы должны использовать параметр id из маршрута, чтобы сделать вызов API. Итак, мы получаем идентификатор с помощью route.paramMap.get(‘id’) и передаем его в метод.
Идите вперед и обновите файл модуля, маршрутизацию профиля и компонент профиля, следуя приведенному выше примеру.
Если все пойдет правильно, вы заметите, что больше не появляется неопределенная ошибка при нажатии на профиль пользователя.
И вот как резольверы работают в Angular.