通过路由器惰性加载模块
惰性加载也就是懒加载,或者说延迟加载,一些模块使用懒加载后,只有当用户第一次导航到这个模块时,才会加载一些特性。这对于应用程序的性能和减小初始包的大小有很大的帮助,其设置也非常简单。
应用路由
app/app-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
export const routes: Routes = [
{ path: '', redirectTo: 'contact', pathMatch: 'full'},
{ path: 'crisis', loadChildren: 'app/crisis/crisis.module#CrisisModule' },
{ path: 'heroes', loadChildren: 'app/hero/hero.module#HeroModule' }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
其中,contact路由并不是在这里定义的。对于带有路由组件的特性模块,其标准做法就是让它们定义自己的路由。如,ContactModule特性模块,在其特性区中定义自己的路由文件contact.routing.ts。
另外两个路由使用惰性加载语法来告诉路由器要到哪里去找这些模块。
{ path: 'crisis', loadChildren: 'app/crisis/crisis.module#CrisisModule' },
{ path: 'heroes', loadChildren: 'app/hero/hero.module#HeroModule' }
惰性加载模块的位置是字符串而不是类型。在本应用中该字符串同时标记出了模块文件和模块类,两者用#分隔开。
对于这些惰性模块(这里指CrisisModule和HeroModule模块),并不需要在根模块AppModule中导入。它们将在用户导航到其中的某个路由时,被异步获取并加载。在AppModule根模块中需要导入ContactModule模块,以便在应用启动时加载它的路由和组件。
RouterModule.forRoot
RouterModule类的forRoot静态方法和提供的配置,被添加到imports数组中,提供该模块的路由信息。
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
该方法返回的AppRoutingModule类是一个路由模块,它同时包含了RouterModule指令和用来生成配置好的Router的依赖注入提供商。
这个AppRoutingModule仅用于应用的根模块。
注:永远不要在特性路由模块中调用RouterModule.forRoot!
只能在应用的根模块AppModule中调用并导入.forRoot的结果。 在其它模块中导入它,特别是惰性加载模块中,是违反设计目标的并会导致一个运行时错误。
路由到特性模块
app/contact目录中也有一个新文件contact-routing.module.ts。 它定义了我们前面提到过的联系人路由,并提供了ContactRoutingModule,就像这样:
@NgModule({
imports: [RouterModule.forChild([
{ path: 'contact', component: ContactComponent }
])],
exports: [RouterModule]
})
export class ContactRoutingModule {}
这次我们要把路由列表传给RouterModule的forChild方法。 该方法会为特性模块生成另一种对象。
注:总是在特性路由模块中调用RouterModule.forChild。
当我们只需要从路由器导航到某个特性模块中的某个组件时,我们就不需要公开它了。如,通过路由器导航到ContactComponent组件,contact.module.ts定义如下:
@NgModule({
imports: [ CommonModule, FormsModule, ContactRoutingModule ],
declarations: [ ContactComponent, HighlightDirective, AwesomePipe ],
providers: [ ContactService ]
})
export class ContactModule { }
现在我们通过路由器导航到ContactComponent,所以也就没有理由公开它了。它也不再需要选择器 (selector)。 也没有模板会再引用ContactComponent。它从 AppComponent 模板中彻底消失了。
路由到惰性加载的模块
惰性加载的HeroModule和CrisisModule与其它特性模块遵循同样的规则。它们和主动加载的ContactModule看上去没有任何区别。
如HeroModule:
@NgModule({
imports: [ CommonModule, FormsModule, HeroRoutingModule ],
declarations: [
HeroComponent, HeroDetailComponent, HeroListComponent,
HighlightDirective
]
})
export class HeroModule { }