角度 6 的主布局插座中的嵌套插座
Posted
技术标签:
【中文标题】角度 6 的主布局插座中的嵌套插座【英文标题】:Nested outlets in master layout outlet in angular 6 【发布时间】:2018-11-29 07:58:03 【问题描述】:我正在构建一个 Angular 6 应用程序,其中有两个单独的屏幕:
-
登录(登录、注册、忘记密码、配置文件)
这些页面不是布局的一部分
布局(仪表板、产品、发票)
这些页面应该共享相同的布局
我的应用是基于模块的,所以我有
app.module.ts account.module.ts dashboard.module.ts products.module.ts invoices.module.ts每个模块都有一个空组件,只包含一个出口,除了布局(包含页眉、正文和页脚)。
我想实现那些路线:
site.com/account/login
site.com
|将导航到仪表板
site.com/dashboard
site.com/products
site.com/invoices
Visual explanation
我添加account.module
没有问题,但是添加layout.module
时不知道如何配置路由
注意:也许我的整个方法都是错误的,但对我来说这是唯一合乎逻辑的事情,因为我有包含组件的模块,我想为可能的延迟加载配置做好准备。
如果我走错了路,请给我建议。
代码
app.module.ts
import BrowserModule from '@angular/platform-browser';
import BrowserAnimationsModule from '@angular/platform-browser/animations';
import NgModule from '@angular/core';
import HttpClientModule from '@angular/common/http';
import RouterModule from '@angular/router';
import AppComponent from './app.component';
import LayoutModule from './layout/layout.module';
import AccountModule from './feature-components/membership/account.module';
@NgModule(
declarations: [
AppComponent,
FetchDataComponent
],
imports: [
BrowserModule.withServerTransition( appId: 'ng-cli-universal' ),
BrowserAnimationsModule,
HttpClientModule,
LayoutModule,
AccountModule,
BrowserAnimationsModule
RouterModule.forRoot([
path: '', component: LayoutOutletComponent ,
path: '**', component: PageNotFoundComponent
]),
],
providers: [],
bootstrap: [AppComponent]
)
export class AppModule
app.component.html
<router-outlet></router-outlet>
account.module.ts
import NgModule from '@angular/core';
import SharedModule from '@app-shared/shared.module';
import LoginComponent from './login/login.component';
import ResetPasswordComponent from './reset-password/reset-password.component';
import ChangePasswordComponent from './change-password/change-password.component';
import RouterModule from '@angular/router';
import AccountOutletComponent from './account-outlet/account-outlet.component';
@NgModule(
imports: [
SharedModule,
RouterModule.forChild(
[
path: 'account', component: AccountOutletComponent,
children: [
path: 'login', component: LoginComponent ,
path: 'reset-password', component: ResetPasswordComponent ,
path: 'change-password', component: ChangePasswordComponent ,
path: '', redirectTo: 'login', pathMatch: 'full'
]
]
)
],
exports: [
LoginComponent,
ResetPasswordComponent,
ChangePasswordComponent
],
declarations: [
AccountOutletComponent,
LoginComponent,
ResetPasswordComponent,
ChangePasswordComponent
]
)
export class AccountModule
所以,这里没有问题,当我添加 layout module
时问题就开始了
import NgModule from '@angular/core';
import CommonModule from '@angular/common';
import RouterModule from '@angular/router';
import NavMenuComponent from './nav-menu/nav-menu.component';
import FooterComponent from './footer/footer.component';
import LayoutOutletComponent from './layout-outlet/layout-outlet.component';
import InvoicesModule from '../feature-components/invoices/invoices.module';
@NgModule(
imports: [
CommonModule,
InvoicesModule,
RouterModule
)],
exports: [
NavMenuComponent,
FooterComponent
],
declarations: [
NavMenuComponent,
FooterComponent,
LayoutOutletComponent
]
)
export class LayoutModule
【问题讨论】:
【参考方案1】:你应该做以下事情
在应用模块中创建路径以加载模块而不是组件 在布局模块中创建路径以加载仪表板、产品和发票模块 在布局组件中设置页眉路由器出口和页脚和/或其他布局元素 在模块仪表板、产品和发票中设置加载组件的路径app.module
RouterModule.forRoot([
path: '', loadChildren: '(PathToLayoutMoudle)#LayoutModule' ,
path: '**', component: PageNotFoundComponent
]),
layout.module
RouterModule.forChild([
path: '', component: LayoutComponent,
children: [
path: 'dashboard',loadChildren:
PathToDashboardMoudle)#DashboardMoudle',
path: 'products',loadChildren:
PathToProductsMoudle)#ProductsMoudle',
path: 'invoices',loadChildren:
PathToInvoicesMoudle)#InvoicesdMoudle',
]
]),
account.module
RouterModule.forChild(
[
path: '', component: AccountOutletComponent,
children: [
path: 'login', component: LoginComponent ,
path: 'reset-password', component: ResetPasswordComponent ,
path: 'change-password', component: ChangePasswordComponent ,
path: '', redirectTo: 'login', pathMatch: 'full'
]
]
【讨论】:
【参考方案2】:我认为你走在正确的道路上。首先你需要处理急切的路由,然后你可以切换到惰性模块。
你需要做什么:
app.module.ts
@NgModule(
imports: [
BrowserModule,
AccountModule,
LayoutModule,
RouterModule.forRoot([
path: '**', component: PageNotFoundComponent
])
],
declarations: [
AppComponent,
PageNotFoundComponent
],
bootstrap: [AppComponent]
)
export class AppModule
layout.module.ts
@NgModule(
imports: [
CommonModule,
RouterModule.forChild([
path: '',
component: LayoutOutletComponent,
children: [
path: 'dashboard',
loadChildren: () => DashboardModule
,
path: 'products',
loadChildren: () => ProductsModule
,
path: '', redirectTo: '/dashboard', pathMatch: 'full'
]
])
],
declarations: [
LayoutOutletComponent
]
)
export class LayoutModule
您需要知道的主要事情是所有角度路线都合并在一个路线配置中。要理解这一点,我建议您观看@deborahk 的great video
你不能只写
path: '', component: LayoutOutletComponent,
并单独导入其他模块(ProductsModule
,DashboardModule
)。嵌套路由应作为子路由提供。
现在,当您配置好所有路由后,您可以轻松切换到延迟加载模块:
path: '',
component: LayoutOutletComponent,
children: [
path: 'dashboard',
loadChildren: 'pathToModule#DashboardModule'
,
path: 'products',
loadChildren: 'pathToModule#ProductsModule'
,
path: '', redirectTo: '/dashboard', pathMatch: 'full'
]
你也可以在 AppModule 中延迟加载 LayoutModule
@NgModule(
imports: [
...
LayoutModule,
RouterModule.forRoot([
path: '', loadChildren: './layout/layout.module#LayoutModule' ,
path: '**', component: PageNotFoundComponent
])
],
...
)
export class AppModule
我在 github 上创建了 ng-nested-outlets 应用程序,请尝试一下。
您也可以通过 Stackblitz Demo
在线试用另见
Angular switch from lazyLoading to 'normal' loading【讨论】:
如果您想增强我的回答,请使用编辑按钮。和我的基本一样。 @yt61 您在布局模块中的配置错误。dashboard, products and invoices
应该是子路由,以便将这些组件放置在布局出口内
@yurzui,所以现在你只是懒加载整个LayoutModule
,我们怎么能懒加载只是ProductsModule
,而Dashboard
要被热切加载?
@yurzui 太棒了!谢谢!有用。现在只有一件事..当我使用--prod发布项目时,当我有:`loadChildren:()=> DashboardModule`它在IIS上失败,抱怨:错误错误:未捕获(承诺):错误:运行时编译器未加载错误:运行时编译器未加载但如果我将其更改为: loadChildren: '(pathToDashModule)#DashboardModule' 它在 iis 上工作正常,但如果我这样做,我可以看到它已打开延迟加载- 我最初不想使用以上是关于角度 6 的主布局插座中的嵌套插座的主要内容,如果未能解决你的问题,请参考以下文章
在 Angular 2+ 中,使用路由器插座和嵌套组件有啥区别