首页 > 解决方案 > 如何在 Angular 中有 2 条具有相同 url 的路由

问题描述

使用角度 9 和角度路由器。

我试图遵循以下线程:Angular 2 different components with same route

我想要实现的是拥有 2 条路由'',如果通过身份验证,则移动到 privateModule,如果没有,则移动到 publicModule。

所以基本上,

如果我通过身份验证并转到www.myApp.com <= PrivateModule 如果我未通过身份验证并转到www.myApp.com <= PublicModule。

我设置了一个 app-routing.module.ts =>

const routes: Routes = [
  {
    matcher: publicMatcher,
    loadChildren: publicModule,
  },
  {
    matcher: privateMatcher,
    loadChildren: privateModule,
    canActivate: [AuthPrivateGuard],
    canActivateChild: [AuthPrivateGuard],
  },
]

然后我有 2 个匹配器,我不知道如何设置它们。因为 url''没有什么可消耗的,我目前有一个无限循环。

export function privateMatcher(segments: UrlSegment[]): UrlMatchResult {
  const key = localStorage.getItem('auth')
  if (key && JSON.parse(key).accessToken) {
    console.log('private')
    return { consumed: segments }
  }
  return null
}



export function publicMatcher(segments: UrlSegment[]): UrlMatchResult {
  const key = localStorage.getItem('auth')
  if (!key || !JSON.parse(key)?.accessToken) {
    console.log({ consumed: segments })
    return { consumed: segments }
  }
  return null
}

我可能错误地使用它们,或者不是实现我想要的好方法?

标签: angularroutes

解决方案


我们可以用这种方法达到同样的效果

  • 考虑到我想路由到 http://localhost:4200/home,创建一个带有私有、公共模块的 home 模块,在 app-routing 中定义这个公共模块的路由路径,如下所示。

应用程序路由.module.ts

const routes: Routes = [
 
    {
      path: 'home',
      loadChildren: () => import('./modules/home/home.module').then(mod => 
      mod.HomeModule)
    },
    ...
  ];

home.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule, ROUTES, Routes } from '@angular/router';
import { AuthService } from '../services/auth.service';
@NgModule({
  declarations: [],
  imports: [
    CommonModule,
    RouterModule
  ],
  providers:[
    {provide:ROUTES,
    useFactory: configHomeRoutes,
  deps: [AuthService],
    multi: true}
  ]
})
export class HomeModule { }

export function configHomeRoutes(authService: AuthService){
  let routes: Routes = [];
  if (authService.isAuthorized()) {
    routes = [
      {
        path: '', loadChildren: () => import('../private/private.module').then(mod => 
        mod.PrivateModule)
      }
    ];
  } else {
    routes = [
      {
        path: '', loadChildren: () => import('../public/public.module').then(mod => 
        mod.PublicModule)
      }
    ];
  }
  return routes;
}

私有模块.ts

@NgModule({
  declarations: [PrivateComponent],
  imports: [
    CommonModule,
    RouterModule.forChild([{path: '', component: PrivateComponent}])
  ]
})
export class PrivateModule { }

公共模块.ts

@NgModule({
  declarations: [PublicComponent],
  imports: [
    CommonModule,
    RouterModule.forChild([{path: '', component: PublicComponent}])
  ]
})
export class PublicModule { }
  • homeModule 中 useFactory 提供程序使用的方法 homeRoutes 仅在我们第一次导航到 /home 路径时执行,这会导致加载第一次加载的模块。为了克服这个错误,我们必须删除路由器中的 /home 路径并重新添加它,如下所示

auth.service.ts

  public isAuthorized(): boolean {
    return this.authorizedSource.value;
  }

  public setAuthorized(value: boolean): void {
    const previous = this.authorizedSource.value;
    this.authorizedSource.next(value);
    if (previous === this.authorizedSource.value) {
      return;
    }
    const i = this.router.config.findIndex(x => x.path === 'home');
    this.router.config.splice(i, 1);
    this.router.config.push(
      {path: 'home', loadChildren: () => import('../../modules/home/home.module').then(mod => mod.homeModule)}
    );
  }

推荐阅读