Создайте преобразователь angular для многократного использования

#javascript #angular #routes #resolver

#javascript #angular #маршруты #преобразователь

Вопрос:

Я ищу способ использовать одно разрешение angular route для использования на всех моих маршрутах, но с разными параметрами:

в настоящее время у меня есть что-то вроде:

    {
        path: 'user/:any',
        component: UserprofileComponent,
        resolve: { ProfiledUser: UserprofileResolver }
      },
  

разрешение profileuser:

  resolve(route: ActivatedRouteSnapshot) {
    return this.GlobalService.Get('/userprofile/admin');
  }
  

На самом деле я ищу способ использовать параметры, которые использует Get функция из GlobalService , для самого преобразователя.

Ранее я создал кое-что, что теоретически могло бы сработать:

   path: 'family/panel',
        component: FamilyCoreComponent,
        canActivate: [PermissionGuardService],
        data: {roles: [0]},
  

где можно активировать защиту разрешений:

   canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<boolean>|boolean {

    var requirementRole = next.data.roles[0];
  

Итак, мой вопрос в том, должен ли я использовать принцип для преобразователя, как я сделал с моей защитой разрешений?

Например, что-то вроде:

   {
    path: 'user/:any',
    component: UserprofileComponent,
    resolve: { ProfiledUser: UserprofileResolver }
    data: {load: 'userprofile/admin'},
  },
  

Было бы это хорошим способом сделать это? если да, то как бы мне это сделать, чтобы сделать это наиболее эффективным?

Комментарии:

1. Ознакомьтесь с этой статьей Medium, которая является довольно хорошим примером того, как использовать преобразователь, а также как повторно использовать компонент в качестве подкомпонента: medium.com/@santibarbat /…

Ответ №1:

отличный вопрос, который тоже заставил меня довольно долго чесать голову :).

Итак, давайте рассмотрим мое решение этой проблемы.

При использовании Resolver у нас есть возможность заменить преобразователь чем угодно (функциями / классами).

 @NgModule({
  imports: [
    RouterModule.forRoot([
      {
        path: 'team/:id',
        component: TeamComponent,
        resolve: {
          team: 'teamResolver'
        }
      }
    ])
  ],
  providers: [
    {
      provide: 'teamResolver',
      useValue: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => 'team'
    }
  ]
})
  

Этот фрагмент взят прямо из документов ng

Итак, в вашем случае вы можете добавить некоторые дополнительные параметры в useValue строку, например

 useValue: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) =>
  new ResolverWithParamsResolver(
          route,
          state,
          "customLink"
      ).resolve()
  

И у ResolverWithParamsResolver вас может получиться что-то вроде следующего фрагмента кода

 export interface ResolverWithParamModel<T> {
  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot,
    linkParam: string
  ): Observable<T> | Promise<T> | T;
}
// Custom resolver
@Injectable()
export class ResolverWithParamsResolver implements ResolverWithParamModel<any> {
  constructor(
    private route: ActivatedRouteSnapshot,
    private state: RouterStateSnapshot,
    private linkParam: string
  ) {}

  resolve(): Observable<any> | Promise<any> | any {
    return of(this.linkParam)
  }
}

  

Итак, теперь у вас будет доступ к вашему linkParam .

Вот демонстрационная версия, которая немного сложнее, чем фрагменты в ответе, которая реализует желаемый эффект.

Примечание:

Если у меня есть 10-15 возможных различных конфигураций для пользовательского преобразователя, я бы, вероятно, создал 10-15 преобразователей, поскольку с первого взгляда будет легче понять, что делает каждый преобразователь.

Отказ от ответственности:

Не уверен, что это лучшее решение, но я думаю, что что-то в этом роде — это то, что вам нужно, если у вас возникнут какие-либо проблемы с реализацией, пожалуйста, создайте демонстрацию stackblitz / codesandbox / plunker, и я сделаю все возможное, чтобы помочь вам 🙂

Комментарии:

1. Та же идея, в лучшем случае создать несколько преобразователей. Подробный и простой для понимания, также, если есть один маршрут / модуль, подвергающийся серьезному рефакторингу, вы измените преобразователь только для этой конкретной области.

2. Я не уверен, что это полностью покрывает то, о чем просил OP. На самом деле я упускаю здесь один ключевой момент — как использовать последующие разрешенные значения в TeamComponent . Я попытался подписаться на «ActivatedRoute.data», но после перехода на другой маршрут и обратно подписка больше не предоставляет значения. Вероятно, это отдельный вопрос — я продолжу искать другие вопросы и, возможно, напишу свой собственный.

3. ну, на самом деле я только что узнал, что при правильной настройке маршрутизации activatedRoute.data генерируются новые разрешенные значения, как и должно быть (возможно, через advanceActivatedRoute from router-state .