每个Angular开发者在学习路由设计时都遇到过如下代码:import{RouterModule,Routes}from'@angular/router';constroutes:Routes=[{path:'',redirectTo:'/index',pathMatch:'full'}];@NgModule({imports:[RouterModule.forRoot(routes)],...})导出类AppModule{}此约定也用于ngx-bootstrap和AngularMaterial。它的命名约定意味着当调用forRoot()方法时,给定的模块必须注册到应用程序的根NgModule中。那为什么需要在应用程序的根模块中调用它,而不是任何其他NgModule?首先,forRoot()合约返回什么数据类型?通常,此方法的返回类型是符合ModuleWithProviders接口的对象。这个接口是一个被接受的NgModule导入并且有两个属性:这与根NgModule有什么关系?事实上,虽然这个约定意味着它应该被导入到应用程序的根目录中,但在很多情况下我们可以将它导入到非根目录的NgModule中,它也能正常工作。下面是一个例子,ngx-bootstrap中的ModalModule使用forRoot()约定:import{NgModule,ModuleWithProviders}from'@angular/core';从'./modal-backdrop.component'导入{ModalBackdropComponent};从'./modal.component'导入{ModalDirective};从'../positioning'导入{PositioningService};从'../component-loader'导入{ComponentLoaderFactory};@NgModule({声明:[ModalBackdropComponent,ModalDirective],出口:[ModalBackdropComponent,ModalDirective],entryComponents:[ModalBackdropComponent]})exportclassModalModule{publicstaticforRoot():ModuleWithProviders{return{ngModule:ModalModule,providers:[ComponentLoaderFactory,PositioningService]};注意:ModalModule不是在@NgModule装饰器中声明任何提供者,而是在静态的forRoot()方法中。尽管调用forRoot()方法理论上可以在子NgModule中工作,但在应用程序的根模块中调用forRoot会带来以下好处。当一个类被@Injectable修饰并注册为NgModule的提供者时,该类被唯一创建一次,并且一个实例在整个应用程序中共享。当Angular引导根NgModule时,所有NgModule中可用的所有导入都会在那时注册并可用于整个应用程序-它们是全局的。这就是为什么在子NgModule中注册的提供者在整个应用程序中都可用。
