在浏览器URL中显示所需的路线

问题描述

我的主模块路由中有这样的路由。

    const routes: Routes = [
    {
        path: '',redirectTo: 'home',pathMatch: 'full',},{
        path: 'home',component: MainComponent,children: [
            {
                path: '',loadChildren: () => import('../HR/human-resources.module').then(m => m.HumanResourcesModule),}
        ]
    }];

和在human-resources-routing.module.ts中,我有这样的路由。

    const routes: Routes = [
    {
        path: '',component: QuestionGroupComponent
            },{
                path: 'reports',component: DatePeriodComponent
            },{
                path: 'states',component: StateWithTopPersonnelComponent
            },{
                path: 'personnel',component: StatePersonnelComponent
            },{
                path: 'personnel-detail',component: PersonnelDetailComponent
            }
        ]
    }];

例如,现在当我想转到DatePeriodComponent时,我有一个类似 http:// localhost:4200 / home / reports 的URL,但是我想显示内容有些不同。 我想显示所有 http:// localhost:4200 / reports 这样的URL,但没有主页。我该如何忽略或阻止在URL中显示

解决方法

我认为解决此问题的一种方法是使用自定义UrlSerializer

DefaultUrlSerializerUrlSerializer的默认实现,例如,它被Router.parseUrl()方法使用:

urlTree = this.urlSerializer.parse(url);

或何时setting the browser's URL(可能是解决问题所需要的时间):

private setBrowserUrl(
      url: UrlTree,replaceUrl: boolean,id: number,state?: {[key: string]: any}) {
    const path = this.urlSerializer.serialize(url);
    state = state || {};
    if (this.location.isCurrentPathEqualTo(path) || replaceUrl) {
      // TODO(jasonaden): Remove first `navigationId` and rely on `ng` namespace.
      this.location.replaceState(path,'',{...state,navigationId: id});
    } else {
      this.location.go(path,navigationId: id});
    }
  }

URL是UrlTree的序列化版本。结果,UrlTree是URL的反序列化版本。 DefaultUrlSerializer使用UrlParser来反序列化URL字符串:

  parse(url: string): UrlTree {
    const p = new UrlParser(url);
    return new UrlTree(p.parseRootSegment(),p.parseQueryParams(),p.parseFragment());
  }

因此,您可以通过提供UrlSerializer的自定义实现来解决此问题:

// In `providers` array
{ provide: UrlSerializer,useClass: CustomImplOfUrlSerializer },

一种可行的(基本的)实现方法是,用DefaultUrlSerializer.serialize(urlTree)替换CustomImplOfUrlSerializer.serialize(urlTree)来改变/home''的返回值:

class CustomImplOfUrlSerializer implements UrlSerializer {
  serialize (urlTree: UrlTree): string {
    const raw = (new DefaultUrlSerializer()).serialize(urlTree);

    return raw.replace('/home','')
  }
}

此外,如果您想进一步了解UrlTree以及为什么有用,我建议您查看this article

,

那是我见过的最简单的方法,而且我现在是全世界最生气的人... 我通过设置一个空字符串来加载默认的模块和组件来做到这一点。我将仪表板模块视为默认模块,并将仪表板组件视为默认组件。现在,当应用启动时,我可以看到此URL http:// localhost:4200

const routes: Routes = [
    {
        path: '',component: MainComponent,canActivate: [AuthGuard],children: [
            {
                path: '',loadChildren: () => import('../dashboard/dashboard.module').then(m => m.DashboardModule),},{
                path: 'HR',loadChildren: () => import('../HR/human-resources.module').then(m => m.HumanResourcesModule),]
    },];

并在我的仪表板模块中

const routes: Routes =
    [
        {
            path: '',component: DashboardComponent
        },];