在Angular开发中,我们经常会遇到一个静态的forRoot方法,需要在导入NgModule时调用,最著名的例子是RouterModule。在Angular应用程序的根目录中注册此模块时,按如下方式导入RouterModule: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有什么关系?也许什么都没有。事实上,虽然这个约定意味着它必须在应用程序的根模块中导入,但在许多情况下您可以在非根模块中导入它并且它会起作用。以下是ModalModule如何在ngx-bootstrap中使用forRoot()约定:从'./modal-backdrop.component'导入{ModalBackdropComponent};从'./modal.component'导入{ModalDirective};从'../positioning'导入{PositioningService};从'../component-loader'导入{ComponentLoaderFactory};@NgModule({声明:[ModalBackdropComponent,ModalDirective],exports:[ModalBackdropComponent,ModalDirective],entryComponents:[ModalBackdropComponent]})exportclassModalModule{publicstaticforRoot():ModuleWithProviders{返回{ngModule:ModalModule,providers:[ComponentLoaderFactory,PositioningService]};}}虽然理论上,导入forRoot()方法的额外提供者。在子ngmodule中是可行的,但是在应用程序的根目录中注册它在很多方面都有帮助。首先,考虑提供程序的注入方式与组件和指令的注入方式不同。通常,当一个类被@Injectable修饰并在NgModule中注册为提供者时,该类只会被创建一次,并且该实例会在整个应用程序中共享。当Angular引导根模块时,所有NgModule中可用的所有导入都会在那时注册,并且可用于整个应用程序——它们是全局的。这就是为什么在子NgModule中注册的提供者在整个应用程序中都可用。
