如何在 Angular 10 中创建自定义重定向器?
How can I create a custom redirector in Angular 10?
我在 angular 项目中使用路由进行站点导航,但是,我想根据各种条件将用户从 root/host URL 重定向,我我不确定 Angular 路由器是否可行。
因此我尝试制作一个 HomeComponent
来处理这些重定向。
这是一个流程图,解释了我要实现的目标:
- 如果用户已登录,他们应该被带到各自的门户 - 用户类型存储在用户的令牌中
- 用户应该只能访问他们被分配到的门户
- 如果用户已登录,则他们应该无法访问登录页面
在我的主要应用程序路由模块中,我有这个:
import { HomeComponent } from './../home/home.component';
import { LoginComponent } from './../login/login.component';
import { Routes, RouterModule, PreloadAllModules } from '@angular/router';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
const appRoutes: Routes = [
{
path: 'login',
component: LoginComponent
},
{
path: 'staff',
loadChildren: () => import('../staff-portal/staff-portal.module').then(m => m.StaffPortalModule)
},
{
path: '**',
component: HomeComponent
},
];
@NgModule({
imports: [
CommonModule,
RouterModule.forRoot(
appRoutes,
{
preloadingStrategy: PreloadAllModules
}
)
],
exports: [RouterModule]
})
export class AppRoutingModule {
}
我的主页(重定向器)组件:
import { AuthService } from './../_services/auth.service';
import { NavigationStart, Router } from '@angular/router';
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-home',
template: ''
})
export class HomeComponent {
constructor(private authService: AuthService, private router: Router) {
if (this.authService.loggedIn)
{
let parsedToken = this.authService.getParsedToken();
if (parsedToken.type === '0')
{
this.router.navigate(['/staff/home']);
return;
}
else if (parsedToken.type === '1')
{
this.router.navigate(['/student/home']);
return;
}
else if (parsedToken.type === '2')
{
this.router.navigate(['/parent/home']);
return;
}
}
this.router.navigate(['/login']);
return;
}
}
我目前遇到的问题是,当用户未登录并导航到根目录时,angular 会尝试显示 HomeComponent
的模板(一个空字符串).
我不完全确定使用组件是实现这种行为的正确方法,这正是我到目前为止设法想出的方法,但请随时提出替代方案。
我建议研究 Route guards 以根据身份验证状态解决路由逻辑问题。
因此,与其在组件内编写重定向逻辑,不如在守卫内保持整洁 class。
路由配置示例:
{
path: '/your-path',
component: YourComponent,
canActivate: [YourGuard],
}
守卫代码示例:
export class YourGuard implements CanActivate {
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): boolean {
// your logic goes here
}
}
将 AuthGuard 与 canLoad 结合使用:
//routes
{
path: 'staff',
loadChildren: () => import('../staff-portal/staff-portal.module').then(m => m.StaffPortalModule),
canLoad: [AuthGuard]
},
//auth-guard.service.ts
import { Router, CanLoad, Route } from '@angular/router';
import { Injectable } from '@angular/core';
import { AuthService } from './auth.service';
@Injectable()
export class AuthGuard implements CanLoad {
constructor(
private authService: AuthService,
private router: Router
) {}
canLoad(route: Route): boolean {
if (this.authService.isLoggedIn()) {
return true;
}
this.router.navigate(['', 'login']);
return false;
}
}
//auth.service.ts
import { LocalStorageService } from './local-storage.service';
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
@Injectable()
export class AuthService {
constructor(
private localStorageService: LocalStorageService,
private router: Router
) {}
login(data) {
this.localStorageService.set('token', data.token);
this.router.navigate(['', 'staff']);
}
logout() {
window.localStorage.clear();
this.router.navigate(['']);
}
isLoggedIn(): boolean {
if (this.localStorageService.get('token')) {
return true;
}
return false;
}
}
我在 angular 项目中使用路由进行站点导航,但是,我想根据各种条件将用户从 root/host URL 重定向,我我不确定 Angular 路由器是否可行。
因此我尝试制作一个 HomeComponent
来处理这些重定向。
这是一个流程图,解释了我要实现的目标:
- 如果用户已登录,他们应该被带到各自的门户 - 用户类型存储在用户的令牌中
- 用户应该只能访问他们被分配到的门户
- 如果用户已登录,则他们应该无法访问登录页面
在我的主要应用程序路由模块中,我有这个:
import { HomeComponent } from './../home/home.component';
import { LoginComponent } from './../login/login.component';
import { Routes, RouterModule, PreloadAllModules } from '@angular/router';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
const appRoutes: Routes = [
{
path: 'login',
component: LoginComponent
},
{
path: 'staff',
loadChildren: () => import('../staff-portal/staff-portal.module').then(m => m.StaffPortalModule)
},
{
path: '**',
component: HomeComponent
},
];
@NgModule({
imports: [
CommonModule,
RouterModule.forRoot(
appRoutes,
{
preloadingStrategy: PreloadAllModules
}
)
],
exports: [RouterModule]
})
export class AppRoutingModule {
}
我的主页(重定向器)组件:
import { AuthService } from './../_services/auth.service';
import { NavigationStart, Router } from '@angular/router';
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-home',
template: ''
})
export class HomeComponent {
constructor(private authService: AuthService, private router: Router) {
if (this.authService.loggedIn)
{
let parsedToken = this.authService.getParsedToken();
if (parsedToken.type === '0')
{
this.router.navigate(['/staff/home']);
return;
}
else if (parsedToken.type === '1')
{
this.router.navigate(['/student/home']);
return;
}
else if (parsedToken.type === '2')
{
this.router.navigate(['/parent/home']);
return;
}
}
this.router.navigate(['/login']);
return;
}
}
我目前遇到的问题是,当用户未登录并导航到根目录时,angular 会尝试显示 HomeComponent
的模板(一个空字符串).
我不完全确定使用组件是实现这种行为的正确方法,这正是我到目前为止设法想出的方法,但请随时提出替代方案。
我建议研究 Route guards 以根据身份验证状态解决路由逻辑问题。
因此,与其在组件内编写重定向逻辑,不如在守卫内保持整洁 class。
路由配置示例:
{
path: '/your-path',
component: YourComponent,
canActivate: [YourGuard],
}
守卫代码示例:
export class YourGuard implements CanActivate {
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): boolean {
// your logic goes here
}
}
将 AuthGuard 与 canLoad 结合使用:
//routes
{
path: 'staff',
loadChildren: () => import('../staff-portal/staff-portal.module').then(m => m.StaffPortalModule),
canLoad: [AuthGuard]
},
//auth-guard.service.ts
import { Router, CanLoad, Route } from '@angular/router';
import { Injectable } from '@angular/core';
import { AuthService } from './auth.service';
@Injectable()
export class AuthGuard implements CanLoad {
constructor(
private authService: AuthService,
private router: Router
) {}
canLoad(route: Route): boolean {
if (this.authService.isLoggedIn()) {
return true;
}
this.router.navigate(['', 'login']);
return false;
}
}
//auth.service.ts
import { LocalStorageService } from './local-storage.service';
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
@Injectable()
export class AuthService {
constructor(
private localStorageService: LocalStorageService,
private router: Router
) {}
login(data) {
this.localStorageService.set('token', data.token);
this.router.navigate(['', 'staff']);
}
logout() {
window.localStorage.clear();
this.router.navigate(['']);
}
isLoggedIn(): boolean {
if (this.localStorageService.get('token')) {
return true;
}
return false;
}
}