当前位置: 首页 > Web前端 > HTML5

Angular应用开发使用ForRoot来解决LazyLoadedModule中单例行为丢失的问题

时间:2023-04-05 00:19:15 HTML5

笔者在Angular实际项目开发中曾经遇到这样一个需求:我们要创建一个共享模块,里面会包含一个设置布尔值的配置(作为标志)启用或禁用其他模块的某些功能。其他模块可以在Angular应用程序的引导过程中加载,或者它们可以是延迟加载的模块。当我们想要跨应用程序维护服务的单个实例(单例)时,将使用ForRoot的使用场景,这些应用程序也将具有延迟加载的模块。例如,看看这个托管在StackBlitz上的演示代码,其中计数器对于急切和延迟加载模块的行为不同。sharedModule的提供者数组导入了这个服务:在这个例子中,我们共享一个服务来跟上计数器值。每当任何组件增加存储在计数器服务中的值时,我都想与所有组件共享它。我在app.routes.ts中定义了一个路由数组routing:上图是通过LazyLoad加载LazyModule,后者的实现:LazyModuleimportsSharedModuletouseitscounterCounterService:问题是当我们尝试引入懒加载模块时。请注意延迟加载的组件如何不共享相同的计数器值。当仅使用预加载组件时,如果您使用共享服务,下面的示例将起作用,但请注意延迟加载组件的行为方式。惰性组件获得它们自己的服务实例。但是这个方案的问题是:我们点击EagerLoad的Component中的Counter按钮,增加counter的值,点击Lazy超链接,进入LazyModule中的Component。我们期望此时Component中显示的值为7:相反,LazyComponent中的值为0:计数器由驻留在SharedModule下的CounterService维护。由于延迟加载的模块创建了自己的服务实例,我们失去了Angular服务的单例行为。为了解决这个问题,我们需要引入forRoot()的概念。在此演示中可以看到一个工作示例。这与我们将它与RouterModule一起使用以帮助RouterService了解具有多个模块的应用程序的行为的原因相同。RouterModule.forRoot(ROUTES)修改方案,SharedModule实现代码:import{NgModule,ModuleWithProviders}from'@angular/core';import{CounterService}from'./counter.service';@NgModule({})exportclassSharedModule{staticforRoot():ModuleWithProviders{return{ngModule:SharedModule,providers:[CounterService]}}}在App中调用该方法模块:从'@angular/core'导入{NgModule};从'@angular/platform-b??rowser'导入{BrowserModule};从'./shared/shared.module'导入{SharedModule};从'./app.component'导入{AppComponent};从'./导入{EagerComponent}eager.component';import{routing}from'./app.routes';@NgModule({imports:[BrowserModule,SharedModule.forRoot(),routing],declarations:[AppComponent,EagerComponent],bootstrap:[AppComponent]})exportclassAppModule{}修改后的代码链接。之后就可以在EagerLoad和LazyLoadComponent之间任意切换,单例模式的行为可以正常工作了。参考资料https://medium.com/slackernoo...https://shashankvivek-7.mediu...https://stackoverflow.com/que...https://angular.io/guide/lazy。..