Почему мои Angular routerLink кнопки не работают при использовании * ngIf с afAuth.user? - PullRequest
0 голосов
/ 12 марта 2020

Мое приложение имеет панель навигации с некоторыми ссылками на различные компоненты. Эти кнопки должны быть видны, только если пользователь вошел в систему, и пользователь подтвердил свою электронную почту. Маршруты к компонентам также защищены Auth Guard.

Вот мой код:

nav.component. html

...
<a 
  *ngIf="(authService.fbUser$ | async)?.emailVerified"
  mat-button
  routerLink="component-1"
  >Component 1</a>
<a
  *ngIf="(authService.fbUser$ | async)?.emailVerified"
  mat-button
  routerLink="component-2"
  >Component 2</a>
<a
  *ngIf="!(authService.authState | async)"
  mat-button
  routerLink="login"
  >Sign in</a
>
<button
  *ngIf="authService.authState | async"
  mat-button
  (click)="signOut()"
>
  Sign out
</button>
...

auth.service.ts

...
export class AuthService {
  fbUser$: Observable<firebase.User | null>;

  constructor(private afAuth: AngularFireAuth, private afs: AngularFirestore) {
    this.fbUser$ = this.afAuth.user;
  }

  get authState() {
    return this.afAuth.authState;
  }
...

Verified-user-guard.ts

...
export class VerifiedUserGuard implements CanActivate {
  constructor(private authService: AuthService, private router: Router) {}

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ):
    | Observable<boolean | UrlTree>
    | Promise<boolean | UrlTree>
    | boolean
    | UrlTree {
    return this.authService.fbUser$.pipe(
      take(1),
      map(user => (user && user.emailVerified)),
      tap(isVerified => {
        if (!isVerified) {
          this.router.navigate(['email-verification-pending']);
        }
        console.log(`Verified user: ${isVerified}`);
      })
    );
  }
}

app-routing. module.ts

...
const routes: Routes = [
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: 'home', component: HomeComponent },
  {
    path: 'component-1',
    loadChildren: () =>
      import('./component-1/component-1.module').then(m => m.ComponentOneModule),
    canActivate: [VerifiedUserGuard]
  },
  {
    path: 'component-2',
    loadChildren: () =>
      import('./component-2/component-2.module').then(m => m.ComponentTwoModule),
    canActivate: [VerifiedUserGuard]
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes), AuthModule],
  providers: [VerifiedUserGuard],
  exports: [RouterModule]
})
export class AppRoutingModule {}
...

РЕДАКТИРОВАТЬ: Когда щелкают ссылки компонента 1 или компонента 2, ничего не происходит. Страница остается прежней.

Я уже несколько дней перебираюсь с этим, и вот что я нашел:

1) Защитные устройства работают, в том случае, если пользователь не проверен и они пытаются получить доступ к маршруту через адресную строку, которую они перенаправляют на страницу, ожидающую подтверждения электронной почты.

2) Если я удаляю защитные средства аутентификации, т. е. закомментирую canActivate: [VerifiedUserGuard] из модуля app-routing кнопки навигации работают в обычном режиме.

3) Если я изменю условие * ngIf в ссылках Компонент 1 и Компонент 2, чтобы оно соответствовало ссылке Выход, т. е. *nfIf="authService.authState | async", то кнопки будут работать, и защитные устройства будут работать.

Так что я не могу понять, где я ошибся. Кажется, что-то связано с использованием afAuth.user в * ngIf, но я действительно не знаю, почему.

РЕДАКТИРОВАТЬ: нет ошибок консоли

РЕДАКТИРОВАТЬ: маршрутизация в Дочерние компоненты выглядят следующим образом:

component-1-routing.module.ts

...
const routes: Routes = [{ path: '', component: ComponentOneHomeComponent }];
...

component-2-routing.module.ts

...
const routes: Routes = [
  {
    path: "",
    component: ComponentTwoHomeComponent,
    children: [
      { path: "", redirectTo: "component-2" },
      { path: "child-1", component: ChildOneComponent },
      { path: "child-2", component: ChildTwoComponent },
      { path: "child-3", component: ChildThreeComponent }
    ]
  }
];
...

1 Ответ

0 голосов
/ 30 марта 2020

Это что-то вроде хака, но я смог обойти мою проблему.

Я добавил метод получения currentUser в службу аутентификации:

get currentUser() {
    return this.afAuth.auth.currentUser;
}

Затем добавил аутентификацию Служба для конструктора моего компонента nav и использовала его в ссылках навигации:

*ngIf="authService.currentUser?.emailVerified"

Это решает мою непосредственную проблему. Недостатком является то, что, поскольку я не подписываюсь на наблюдаемый, компонент не обновляется, когда пользователь проверяет свой адрес электронной почты. Я прочитал о проблемах angular на GitHub, что вы не можете прослушивать изменения при проверке электронной почты, поэтому, возможно, это не имеет значения.

...