(八)共享相同的依赖注入树

来源:互联网 发布:mac的作图软件 编辑:程序博客网 时间:2024/05/18 02:13

原文链接:https://angular-2-training-book.rangle.io/handout/modules/shared-di-tree.html

到目前为止,我们的问题是我们正在DI树的不同级别创建相同服务的两个实例。 在树的下部分支中创建的实例正在遮蔽根级别定义的实例。 解决方案? 为避免为延迟加载的模块在DI树的较低级别创建第二个实例,并且仅使用在树根的注册的服务实例。

为了实现这一点,我们需要修改SharedModule的定义,而不是在providers属性中定义我们的服务,我们需要创建一个名为forRoot的静态方法,该方法与模块本身一起导出服务。

app/shared/shared.module.ts

import { NgModule, ModuleWithProviders } from '@angular/core';import { CounterService } from './counter.service';@NgModule({})export class SharedModule {  static forRoot(): ModuleWithProviders {    return {      ngModule: SharedModule,      providers: [CounterService]    };  }}

通过这个设置,我们可以在我们的根模块AppModule导入这个模块,调用forRoot方法来注册模块和服务。

app/app.module.ts

...import { SharedModule } from './shared/shared.module';@NgModule({  imports: [    SharedModule.forRoot(),    ...  ],  ...})export class AppModule {}

我们应该只在根应用程序模块中调用forRoot ,而不在其他地方。 这确保在根级别上只存在一个服务实例。 在另一个模块中调用forRoot可以在DI树的不同级别重新注册该服务。

由于SharedModule只包含Angular在根应用程序注入器中注册的服务,因此我们不需要将其导入到LazyModule 。 这是因为延迟加载的模块已经可以访问在根级别定义的服务。

查看示例

这一次,当我们改变counter属性的值时,这个值在EagerComponent和LazyComponent之间共享,证明我们正在使用相同的CounterService实例。

然而,我们很可能在SharedModule中定义了SharedModule在另一个模块中需要的组件,管道或指令。 以下列为例。

app/shared/shared.module.ts

import { NgModule, ModuleWithProviders } from '@angular/core';import { CounterService } from './counter.service';import { HighlightDirective } from './highlight.directive';@NgModule({  declarations: [HighlightDirective],  exports: [ HighlightDirective ]})export class SharedModule {  static forRoot(): ModuleWithProviders {    return {      ngModule: SharedModule,      providers: [CounterService]    };  }}

在这里,我们声明并导出HighlightDirective因此导入SharedModule其他模块可以在其模板中使用它。 这意味着我们可以正常地在LazyModule导入模块。

app/lazy/lazy.module.ts

import { NgModule } from '@angular/core';import { SharedModule } from '../shared/shared.module';import { LazyComponent }   from './lazy.component';import { routing } from './lazy.routing';@NgModule({  imports: [    SharedModule,    routing  ],  declarations: [LazyComponent]})export class LazyModule {}

现在我们可以在LazyModule使用这个指令, LazyModule需要创建另一个CounterService实例。

查看示例

原创粉丝点击