Скрыть навигационную панель в angular 8 (маршруты auth-guard не записываются в route.event) - PullRequest
1 голос
/ 03 апреля 2020

Все,

Перед внедрением аутентификации я смог скрыть свой Navbar от экрана входа в систему и регистрации. Читая события маршрута в component.ts и скрывая панель навигации с помощью ngIf. После того, как я реализовал функцию проверки подлинности, маршрут, проложенный программой проверки подлинности на страницу входа, не скрывает панель навигации, приведенную ниже. Мой код ...

Здесь моя служба проверки подлинности проверяет, прошел ли пользователь проверку подлинности или нет из службы проверки подлинности ( Который будет получать данные от Cognito). Теперь, как я могу скрыть навигационную панель от маршрутов, происходящих от охраны. Пожалуйста, помогите

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;
        }
      }
    });
  }}

route.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 { }

служба охраны:

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); 
        }); 
       } 
}

1 Ответ

4 голосов
/ 05 апреля 2020

Вместо того, чтобы показывать или скрывать панель инструментов на основе текущего URL, я бы вместо этого структурировал ваши маршруты и использовал компоненты макета.

authenticated-layout.component. html

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

anonymous-layout.component. html

<router-outlet></router-outlet>

Вы можете наследовать эти макеты (и средства проверки подлинности) с помощью дочерних маршрутов.

route.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 { }

DEMO: https://stackblitz.com/edit/angular-jzmw3d

Альтернатива

В конечном итоге, ваша логика c - это то, что вы хотите показывать панель навигации только тогда, когда пользователь вошел в систему. Вы можете настроить видимость через подписку на службу аутентификации.

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();
  }
}

Я бы по-прежнему рекомендовал использовать дочерние маршруты с одним auth guard в родительском.

Кроме того, я рекомендую вернуть UrlTree из 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); 
    }); 
  };
}
...