【问题标题】:Angular 2 Router Wildcard handling with child-routesAngular 2 路由器通配符处理与子路由
【发布时间】:2019-04-15 15:27:40
【问题描述】:

当使用 angular2 的路由器“3.0”的子路由时,无需在父路由器配置中声明它们(之前,您必须在父组件中执行类似 /child... 的操作)。

我想配置一个全局“找不到页面”处理程序,我可以这样做:

{ path: '**', component: PageNotFoundComponent }

在我的应用路由模块中。

警告:如果我这样做,路由器会导航到在 PageNotFoundComponent 之前的应用程序路由模块中声明的路由。但是当我尝试访问子路由时它总是导航到通配符路由(在某些子路由模块中使用RouterModule.forChild 声明。

直观地说,通配符路由应该放在所有其他路由配置之后,因为路由器按声明顺序解析。但是似乎没有办法在子路由之后声明它。在所有子路由器模块中声明通配符路由似乎也不是很优雅。

我是否遗漏了什么,或者在使用子路由时无法在 Angular-2-Router-3 中定义全局 404 页面?

【问题讨论】:

  • 今天(第 5 版)似乎不再是这种情况了。无论声明的顺序如何,在尝试不太具体的路径之前似乎都会匹配更具体的路径。

标签: angular


【解决方案1】:

您可以轻松地使用集中式通配符路由,即用于站点范围的“未找到页面”组件。只需将其提取到一个单独的路由模块中,该模块会被包含在所有其他包含子路由的模块之后。

因此,通配符路由确实位于最后位置,并且不会隐藏任何后续模块的路由。

通配符路由模块或'page not found'路由模块:

@NgModule({
    imports: [
        RouterModule.forChild([
            {
                path: '**',
                component: NotFoundComponent
            }
        ])
    ],
    declarations: [
        NotFoundComponent
    ],
    exports: [
        RouterModule
    ]
})
export class WildcardRoutingModule { }

应用模块:

@NgModule({
    imports: [
        BrowserModule,

        AppRoutingModule, // Has forRoot routes 

        HomeModule, // Has forChild routes 
        LoginModule, // Has forChild routes
        ProductModule, // Has forChild routes
        DiagnosticsModule, // Has forChild routes

        WildcardRoutingModule // Last position
    ],
    declarations: [
        AppComponent  
    ],
    providers: [
    ],
    bootstrap: [AppComponent]
})
export class AppModule {
}

【讨论】:

  • 一件小事:NotFoundComponent 必须是 declared 某处。我在“找不到页面”路由模块中做到了。
  • 整洁!我也试图弄清楚这一点。我意识到基于这个解决方案,另一种方法是在所有子模块之后导入 AppRoutingModule。
  • @David:刚刚将它添加到 WildcardRoutingModule。
  • 谢谢@David 我真的很喜欢你!有史以来最好的问题,现在也是最好的评论:)
  • @MathieuRenda - 如何处理延迟加载的模块?
【解决方案2】:

简单的解决方案是在 app 模块文件的 'imports' 数组中重新排序模块 - 确保 app/root 路由器是数组中的最后一项;例如

@NgModule({ 进口:[FeatureModule1,FeatureModule2,FeatureModule3,AppRouterModule] ... ... })

【讨论】:

  • 即便如此,我仍然得到应用路由配置位于功能路由配置之上。
  • 是的,顺序很重要
【解决方案3】:

我为您准备了以下示例。 /-route 重定向到 /app-route 并在您的父 AppComponent<router-outlet> 内显示 StartComponentStartComponent 本身在其模板中还有另一个 <router-outlet>,路由器在其中加载子组件。

const appRoutes: Routes = [
    {
        path: '',
        redirectTo: 'app',
        pathMatch: 'full',
    },
    {
        path: 'app',
        component: StartComponent,
        children: [
            {
                path: '',
                redirectTo: 'welcome'
            },
            {
                path: 'welcome',
                component: WelcomeComponent
            },
            {
                path: 'settings',
                component: SettingsComponent
            },            
        ]
    },
    {
        path: '**',
        component: PageNotFoundComponent 
    }    
];

最后一个路由是带有**-path 的通配符路由。如果您导航到未知的 URL,例如 /test123 或子组件 /app/test123,它将显示。

pathMatch: 'full' 表示路由器正在寻找相等的路由。这对重定向很重要。

如果您的孩子还需要PageNotFoundComponent,您也可以为他们添加通配符。

{
    path: 'app',
    component: StartComponent,
    children: [
        {
            path: '',
            redirectTo: 'welcome'
        },
        {
            path: 'welcome',
            component: WelcomeComponent
        },    
        {
            path: '**',
            component: ChildrenPageNotFoundComponent
        },      
    ]
}

【讨论】:

  • 感谢您的回答。您所描述的与我所想的不完全一样——我正在考虑angular.io/docs/ts/latest/guide/router.html 上的里程碑#4 中的示例。它们在crisis-center-routing.module.ts 中定义了路由,但在app-routing.module.ts 中没有定义。我想在应用路由模块中定义全局 404 处理程序。
  • 我也需要这个,因为我的功能模块定义了自己的路线。
  • 路径:'**' 是否覆盖路径:''?
猜你喜欢
  • 2019-10-17
  • 2016-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-23
  • 2017-03-04
相关资源
最近更新 更多