Условный рендеринг разных компонентов на одном маршруте (угловой)

#angular #typescript #angular-ui-router #router #angular-router

#angular #typescript #angular-ui-router #маршрутизатор #angular-маршрутизатор

Вопрос:

У меня есть 2 отдельных представления, одно для домашней страницы, а другое для аутентификации; Я хочу отображать LoginComponent по маршруту '/' и SignupComponent по маршруту '/signup' , если пользователь НЕ вошел в систему, иначе отображать компоненты домашней страницы. Я пробовал использовать 2 разных выхода маршрутизатора для домашней страницы и авторизации (но это показывает, что маршрут '/signup' не настроен). Вот мой код

  • app.component.html

 <div *ngIf="logged$ | async; else login">
  <app-header></app-header>
  <router-outlet></router-outlet>
  <!-- ? Primary Outlet -->
</div>
<ng-template #login>
  <router-outlet name="auth"></router-outlet>
  <!-- ? Secondary Outlet for Auth  -->
</ng-template>

 
  • app.component.ts

 @Component({ ... })
export class AppComponent {
  logged$: Observable<boolean>;

  constructor(private store: Store<State>) {
    this.logged$ = store.select('logged');
  }
}

 
  • app-routing.module.ts

 const routes: Routes = [
  { path: '', children: [/* Homepage Components */] },
  {
    path: '',
    children: [
      { path: '', component: LoginComponent },
      { path: 'signup', component: SignupComponent },
    ],
    outlet: 'auth',
  },
];

@NgModule({ ... })
export class AppRoutingModule {}

 

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

1. Не было бы проще / лучше использовать guard и перенаправлять на / login?

2. Я новичок в Angular (я начал вчера) и разработке программного обеспечения в целом (около 4-5 месяцев), не могли бы вы немного объяснить, что такое / как работают охранники?

Ответ №1:

Вместо отображения двух страниц по одному и тому же URL создайте защиту. Защита будет вызвана перед переходом к URL, и в этом примере перенаправит вас на вход в систему, если у вас нет токена (здесь мы предполагаем, что у вас есть AuthService hasAuthToken метод with)

 @Injectable({
  providedIn: 'root',
})
export class AuthGuard implements CanActivate {

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

  canActivate(): boolean {
    if (this.auth.hasAuthToken()) {
      return true;
    }
    this.router.navigate(['/login']);
    return false;
  }
 

Маршрутизация:

 const routes: Routes = [
  { 
    path: '',
    children: [/* Homepage Components */],
    canActivate: [AuthGuard] // Added here
  },
  {
    path: '',
    children: [
      { path: '', component: LoginComponent },
      { path: 'signup', component: SignupComponent },
    ],
    outlet: 'auth',
  },
];

@NgModule({ ... })
export class AppRoutingModule {}