Angular2 条件路由
Angular2 conditional routing
这可能是一个基本问题,但是在 Angular2 中有什么方法可以进行条件路由吗?或者,有人会在路由器外这样做吗?
我知道 ui-router 有一些能力可以做到这一点,但我没有在 Angular2s router 中看到任何类似的东西
更新
在新的router guards中可以改用
https://angular.io/guide/router#milestone-5-route-guards
原始(用于已久的路由器)
实现 CanActivate
生命周期挂钩,如此处所示 和 return false 如果您想阻止导航。
另见 https://angular.io/docs/ts/latest/api/router/CanActivate-var.html
如前所述,Angular Route Guards 是实现条件路由的好方法。由于 Angular 教程在这个主题上有点冗长,这里是一个简短的总结如何使用它们的例子。
1. 守卫有几种类型。如果您需要一些逻辑 if (loggedIn) {go to "/dashboard"} else { go to "/login"}
,那么您正在寻找的是 CanActivate
-Guard。 CanActivate 可以读作"The new route X can be activated if all of the conditions Y are satisfied"。您还可以定义重定向等副作用。如果这不符合您的逻辑,请查看 Angular 教程页面以查看其他守卫类型。
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-conditional-routing
如果您需要渲染特定组件而不是重定向到它,您可以这样做:
const appRoutes: Routes = [
{
path: '' ,
component: (() => {
return SessionService.isAnonymous() ? LoginComponent : DashboardComponent;
})()
}
]
我将此示例用于登录页面,之前未登录的用户将看到登录页面或仪表板仪表板。
更新
此代码将在开发环境中运行,但不会构建,您将收到此错误:
'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
},
]
这可能是一个基本问题,但是在 Angular2 中有什么方法可以进行条件路由吗?或者,有人会在路由器外这样做吗?
我知道 ui-router 有一些能力可以做到这一点,但我没有在 Angular2s router 中看到任何类似的东西
更新
在新的router guards中可以改用 https://angular.io/guide/router#milestone-5-route-guards
原始(用于已久的路由器)
实现 CanActivate
生命周期挂钩,如此处所示
如前所述,Angular Route Guards 是实现条件路由的好方法。由于 Angular 教程在这个主题上有点冗长,这里是一个简短的总结如何使用它们的例子。
1. 守卫有几种类型。如果您需要一些逻辑 if (loggedIn) {go to "/dashboard"} else { go to "/login"}
,那么您正在寻找的是 CanActivate
-Guard。 CanActivate 可以读作"The new route X can be activated if all of the conditions Y are satisfied"。您还可以定义重定向等副作用。如果这不符合您的逻辑,请查看 Angular 教程页面以查看其他守卫类型。
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-conditional-routing
如果您需要渲染特定组件而不是重定向到它,您可以这样做:
const appRoutes: Routes = [
{
path: '' ,
component: (() => {
return SessionService.isAnonymous() ? LoginComponent : DashboardComponent;
})()
}
]
我将此示例用于登录页面,之前未登录的用户将看到登录页面或仪表板仪表板。
更新 此代码将在开发环境中运行,但不会构建,您将收到此错误:
'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
},
]