首页 > 解决方案 > 角度路由正确的方法来为相同的路径使用不同的组件

问题描述

我对 Angular 路由有疑问我有两个模块 Basic 和 Dashboard

在基本模块中,我可以为非默认城市传递城市参数(对于默认城市,它应该在没有参数的情况下工作,例如,如果纽约是默认城市,则路径将为http://my.domain/new-york和 APP应该使用 HomeComponent)但不是默认应用程序应该使用路径http://my.domain/los-angeles并使用相同的组件。我从后端获得的城市列表。我的结构的下一级是类别。我也有来自后端的类别,但如果我尝试访问http://my.domain/category我有HomeComponent而不是SearchComponent。处理这个问题的正确方法是什么?

我需要:

http://my.domain/category -> SearchComponent
http://my.domain/city/category -> SearchComponent
http://my.domain/city -> HomeComponent
http://my.domain/ -> HomeComponent

应用路由配置:

const routes: Routes = [
  {
    path: 'dashboard',
    canActivate: [AuthService],
    loadChildren: () => import('./modules/dashboard/dashboard.module').then(mod => mod.DashboardModule)
  },
  {
    path: '',
    loadChildren: () => import('./modules/basic/basic.module').then(mod => mod.BasicModule),
    runGuardsAndResolvers: 'always'
  },
  {
    path: '**',
    redirectTo: '/'
  }
];

基本模块路由

const routes: Routes = [
  {
    path: '',
    component: BasicComponent,
    children: [
      {
        path: '',
        component: HomeComponent,
        data: {
          headerDark: true
        }
      },
      {
        path: 'search',
        component: SearchComponent,
        pathMatch: 'full'
      },
      {
        path: ':city',
        component: HomeComponent,
        data: {
          headerDark: true
        },
      },
      {
        path: ':category',
        component: SearchComponent
      },
      {
        path: ':city/:category',
        component: SearchComponent
      },
      {
        path: ':city/search',
        component: SearchComponent,
        data: {
          headerDark: true
        }
      }
    ]
  }
];

标签: angularangular-routing

解决方案


我认为您可以通过实现自定义来解决它UrlMatcher

这是 的类型定义UrlMatcher

export type UrlMatchResult = {
  consumed: UrlSegment[];
  posParams?: {[name: string]: UrlSegment};
};

export type UrlMatcher = (segments: UrlSegment[], group: UrlSegmentGroup, route: Route) =>
    UrlMatchResult|null;

AngulardefaultUrlMatcher为每个路由配置对象使用一个。它的作用是确定位置参数(例如:city)和消费段(与发出的 URL 匹配的段):

/* ... */
for (let index = 0; index < parts.length; index++) {
  const part = parts[index];
  const segment = segments[index];
  const isParameter = part.startsWith(':');
  if (isParameter) {
    posParams[part.substring(1)] = segment;
  } else if (part !== segment.path) {
    // The actual URL part does not match the config, no match
    return null;
  }
}

return {consumed: segments.slice(0, parts.length), posParams};

考虑到这一点,我们可以创建一个UrlMatcher如下所示的自定义:

const cityMatcher: UrlMatcher = (segments, group, route) => {
  // you'll have to find the issued city name from `segments`
  // simply use console.log(segments) to find the proper way to do it
  // after you've found the name of the city, check if it is in the list of cities

  // if NOT in the list
  return null

  // if it is there
  return {
    consumed: segments.slice(0, 1),
    posParams: { city: nameOfTheFoundCity }
  }
}

并且可以这样使用:

{
  {
    path: ':city',
    component: HomeComponent,
    data: {
      headerDark: true
    },
    matcher: cityMatcher
  },
}

相同的方法可用于:category.


推荐阅读