如何在 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;
    }
}