Angular2 условная маршрутизация

Это может быть основной вопрос, но в Angular2 есть ли способ сделать условную маршрутизацию? Или кто-то сделает это за пределами маршрутизатора?

Я знаю, что у u-router была какая-то возможность сделать это, но я не видел ничего подобного в маршрутизаторе Angular2s

Ответы

Ответ 1

Обновление

В новых маршрутизаторах можно использовать https://angular.io/docs/ts/latest/guide/router.html#!#guards

оригинал (для длинного маршрутизатора)

Внедрите крючок CanActivate жизненного цикла, как показано здесь Перехват жизненного цикла в маршрутизаторе Angular2, и верните false, если вы хотите предотвратить навигацию. См. Также https://angular.io/docs/ts/latest/api/router/CanActivate-var.html

Ответ 2

Как уже упоминалось, Angular Маршрутные гвардии - хороший способ реализации условных маршрутов. Поскольку учебник Angular является немногословным в этой теме, вот краткое резюме, как использовать их с примером.

1. Существует несколько типов охранников. Если вам нужна логика if (loggedIn) {go to "/dashboard"} else { go to "/login"}, то вы ищете CanActivate -Guard. CanActivate можно читать как "Новый маршрут X можно активировать, если все условия Y выполнены". Вы также можете определить побочные эффекты, такие как перенаправления. Если это не соответствует вашей логике, просмотрите страницу Angular Tutorial, чтобы увидеть другие типы защиты.

2. Создайте auth-guard.service.ts.

3. Заполните auth-guard.service.ts следующим кодом:

import { Injectable } from '@angular/core';
import {CanActivate, Router, RouterStateSnapshot, ActivatedRouteSnapshot} from '@angular/router';

@Injectable()
export class AuthGuardService implements CanActivate {

  constructor(
    private router: Router
  ) {}

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    const isLoggedIn = false; // ... your login logic here
    if (isLoggedIn) {
      return true;
    } else {
      this.router.navigate(['/login']);
      return false;
    }
  }

}

4. Зарегистрируйте auth-guard.service.ts в своем маршрутном модуле. Кроме того, добавьте пару ключ-значение canActivate:[AuthGuardService] ко всем маршрутам, которые вы хотите защитить. Он должен выглядеть примерно так:

const appRoutes: Routes = [
  { path: '', component: LandingComponent},
  { path: 'login', component: LoginComponent},
  { path: 'signup', component: SignUpComponent},
  { path: 'home', component: HomeComponent, canActivate: [AuthGuardService]},
  { path: 'admin', component: AdminComponent, canActivate: [AuthGuardService]},
  { path: '**', component: PageNotFoundComponent }
];

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

Это должно заставить вас начать.

Здесь минималистическая демонстрация: https://stackblitz.com/edit/angular-gltybk

Ответ 3

Если вам нужно отобразить конкретный компонент, а не перенаправить его, вы можете сделать что-то вроде этого:

const appRoutes: Routes = [
  {
    path: '' ,
    component: (() => {
      return SessionService.isAnonymous() ? LoginComponent : DashboardComponent;
    })()
  } 
]

Я использовал этот пример для целевой страницы, где пользователь, который ранее не был зарегистрирован, либо видел целевую страницу, либо панель мониторинга панели.

Обновление Этот код будет работать в среде dev, но он не будет создан, и вы получите эту ошибку:

ОШИБКА в ошибке при компиляции шаблона 'AppRoutingModule' Выражения функции не поддерживаются в декораторах в 'ɵ0'   'ɵ0' содержит ошибку в src/app/app.routing-module.ts(14,25)     Рассмотрим изменение выражения функции в экспортируемой функции.

Чтобы исправить это, я создал отдельный модуль, который выглядит следующим образом

import {LandingPageComponent} from '../landing-page/landing-page.component';
import {DashboardComponent} from "../dashboard/dashboard.component";
import {SessionService} from "../core/services/session.service";

const exportedComponent = SessionService.isAnonymous() ? LandingPageComponent : DashboardComponent;

export default exportedComponent;

а затем вам просто нужно импортировать модуль, предоставленный этим "factory"

import LandingPageComponent from './factories/landing-factory.component';
const appRoutes: Routes = [
  {
    path: '' ,
    component: LandingPageComponent
  },
]