首页 > 解决方案 > 隐藏 Angular 8 中的导航栏(auth-guard 路由未记录在 routes.event 中)

问题描述

全部,

在实施 auth 保护之前,我能够从登录和注册屏幕中隐藏我的导航栏。通过读取 component.ts 中的路由事件并通过 ngIf 隐藏导航栏。在我实施 auth guard 之后,auth guard 到登录页面的路线没有隐藏下面的导航栏是我的代码..

在这里,我的身份验证服务将检查用户是否已通过身份验证服务进行身份验证(将从 cognito 获取数据)。现在,我怎样才能从 auth 守卫发生的路线中隐藏导航栏。请帮忙

app.component.html

<app-toolbar *ngIf="isShowNavbar"   ></app-toolbar>

<router-outlet></router-outlet>

app.component.ts

import { Component,OnInit } from '@angular/core';
import {AuthorizationService} from "./authorization.service";
import { Router, ActivatedRoute, UrlSegment, NavigationEnd } from '@angular/router';
import { Observable } from 'rxjs';
import { first, distinctUntilChanged, throttleTime } from '../../node_modules/rxjs/operators';
@Component({
  // tslint:disable-next-line: component-selector
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit  {

  isLoggedIn$: Observable<boolean>;
  isShowNavbar: boolean;
  constructor(private auth: AuthorizationService,private router: Router) {}
  ngOnInit() {
    this.isLoggedIn$ = this.auth.IsLoggedIn;
    this.router.events.pipe(throttleTime(100), distinctUntilChanged()).subscribe((navEnd: NavigationEnd) => {
      console.log(navEnd.url)
      if (navEnd) {
        if (navEnd.url === "/login" || navEnd.url ==="/register" ) {
          this.isShowNavbar = false
        } else {
          this.isShowNavbar = true;
        }
      }
    });
  }}

路线.ts

const routes: Routes = [
  {path: '', redirectTo: '/cards', pathMatch: 'full',canActivate :  [ AuthGuardService ] },
  { path: 'shareditems', component: ShareditemsComponent,canActivate :  [ AuthGuardService ] },
  { path: 'home', component: AppCardsComponent,canActivate :  [ AuthGuardService ]  },
  { path: 'calendar', component: CalendarComponent,canActivate :  [ AuthGuardService ] },
  {path: 'lan', component: LanComponent,canActivate :  [ AuthGuardService ] },
  {path:'login', component:LoginComponent},
  {path: 'register', component:RegisterComponent },
  {path:'nav', component:CommonComponent,canActivate :  [ AuthGuardService ] }

];

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

auth.guard 服务:

canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean>
{ 
    return this.auth.isAuthenticated() 
      .then(data => { 
          return Promise.resolve(true); 
        }).catch(err => { 
           this._router.navigate(['/login']); 
           return Promise.resolve(false); 
        }); 
       } 
}

标签: angularangular8angular-routingauth-guardangular-guards

解决方案


我不会根据当前 URL 显示或隐藏您的工具栏,而是构建您的路线并使用布局组件。

认证的layout.component.html

<app-toolbar></app-toolbar>
<router-outlet></router-outlet>

匿名布局.component.html

<router-outlet></router-outlet>

您可以通过使用子路由继承这些布局(和身份验证保护)。

路线.ts

const routes: Routes = [
  { path: '', component: AuthenticatedLayoutComponent, canActivate : [ AuthGuardService ], 
    children: [
    { path: '', redirectTo: '/cards', pathMatch: 'full' },
    { path: 'shareditems', component: ShareditemsComponent },
    { path: 'home', component: AppCardsComponent },
    { path: 'calendar', component: CalendarComponent },
    { path: 'lan', component: LanComponent },  
    { path:'nav', component: CommonComponent }
  ] },
  { path: '', component: AnonymousLayoutComponent, children: [
    { path:'login', component: LoginComponent},
    { path: 'register', component: RegisterComponent },
  ] }
];

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

演示:https ://stackblitz.com/edit/angular-jzmw3d

选择

最终,您的逻辑是您只想在用户登录时显示导航栏。您可以通过订阅您的身份验证服务来设置可见性。

app.component.ts

export class AppComponent implements OnInit  {

  isLoggedIn$: Observable<boolean>;
  isShowNavbar: boolean;

  constructor(private auth: AuthorizationService,private router: Router) {}

  private destroyed$ = new Subject();

  ngOnInit() {
    this.isLoggedIn$ = this.auth.IsLoggedIn;
    this.isLoggedIn$.pipe(
      takeUntil(this.destroyed$)
    ).subscribe(isLoggedIn => {
      this.isShowNavbar = isLoggedIn;
    });
  }

  ngOnDestroy() {
    this.destroyed$.next();
    this.destroyed$.complete();
  }
}

不过,我仍然建议在父级中使用带有单个身份验证保护的子路由。

另外,如果您想指示路由器导航到新路由,我建议您返回UrlTreefrom 。canActivate

auth-guard.service.ts

canActivate (next: ActivatedRouteSnapshot, state: RouterStateSnapshot
): Promise<boolean | UrlTree> { 
  return this.auth.isAuthenticated() 
    .then(data => { 
      return Promise.resolve(true); 
    }).catch(err => { 
      const urlTree = this._router.parseUrl('/login');
      return Promise.resolve(urlTree); 
    }); 
  };
}

推荐阅读