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
},
]