Angular загружает роли пользователей из ядра перед использованием Guard

пожалуйста, у меня действительно есть app.module, который загружает основной модуль посредством отложенной загрузки. И я загружаю роли в основном компоненте в хранилище. Затем у меня есть ролевой охранник, который заходит в магазин, чтобы посмотреть эти роли. Когда я загружаю некоторую /home-страницу, а затем перехожу на страницу, к которой применена защита ролей, все в порядке, потому что роли уже загружены. Однако, когда я ввожу в браузер URL-адрес непосредственно того, к которому применяется защита роли, это дает сбой. Он загружает app.module, но больше не загружает core.module, а загружает охрану. Где нет ролей, и даже когда я пробовал через скип, пока так, все равно не получилось. Есть идеи, что с этим делать? Большое спасибо

Модуль AppRoutingModule

        {
    path: '',
    children: [{
      path: '', loadChildren: () => import('./core/core.module').then(m => m.CoreModule)
    }]
  },

Модуль CoreRoutingModule

      {
    path: '',
    component: CoreComponent,
    children: [
      {
        path: "test,
        loadChildren: () => import('@modules/test/test.module').then(m => m.TestModule),
        canActivate: [MyGuard]
    ......

CoreComponent

        ngOnInit(): void {
    this.authFacade.initAll();
    this.authFacade.loginCheck();
  }  

AuthGuard — только для теста

      canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> {
    return this.authFacade.user$.pipe(
      skipWhile(user => user === undefined),
      take(1),
      map(user => {
        console.log(user);
        if (!user)
          return false;

        return true;
      })
    )
  }

1 ответ

Это может быть связано с тем, что роли загружаются асинхронно в вашемCoreComponentи охранник оценивается перед тем, как роли будут выбраны и сохранены.

Вы можете попробовать это:

      //CoreComponnet
ngOnInit(): void {
  this.authFacade.initAll();
  this.authFacade.loginCheck();

  this.authFacade.rolesLoaded$.pipe(
// wait until roles are loaded
    filter(loaded => loaded), 
// only happens once
take(1) 
  ).subscribe(() => {
    // roles loaded
  });
}

и

      //AuthGuard
canActivate(
  route: ActivatedRouteSnapshot,
  state: RouterStateSnapshot
): Observable<boolean> {
  return combineLatest([
    this.authFacade.user$,
 // something to track roles loading
    this.authFacade.rolesLoaded$
  ]).pipe(
    skipWhile(([user, rolesLoaded]) => user === undefined || !rolesLoaded),
    take(1),
    map(([user, rolesLoaded]) => {
      if (!user) {
        return false;
      }

      // check user's roles against necesary roles for the route
      // add logic here to see if the user has the required roles

      return true;
    })
  );
}

Другие вопросы по тегам