为什么我可以在不导入服务提供商模块的情况下使用服务?

时间:2018-08-22 08:10:58

标签: angular service module lazy-loading

我试图研究一个角度应用程序中的多个NgModule如何一起工作,尤其是我试图了解如何将提供常用服务的SharedModule正确地导入到延迟加载的特征模块中。

逐步:

  • 我创建了一个新的角度应用程序:ng new playground --routing
  • 我创建了一个SharedModule,旨在提供服务和常用的声明对象:ng generate module shared
  • 我在共享模块内创建服务:ng generate service shared/foo
  • 现在,我在FooService的目录中有一个SharedModule,但是我希望该服务由SharedModule提供。因此,我将@Injectable批注更改为:

    @Injectable({
        providedIn: SharedModule
    })
    
  • 因为我想保持我的AppModule及其服务注入器尽可能的干净(在现实世界中,我还将使用CoreModule,但这不属于我的范围。问题,让我们回到正轨)

  • 现在,我想添加一个新功能,因此生成了一个我想延迟加载的新FeatureModule:ng generate module feature --routing
  • 现在,我有一个FeatureModule
  • 让我们通过向AppRoutingModule添加路由来延迟加载功能模块:

    const routes: Routes = [
      {
        path: 'feature',
        loadChildren: './feature/feature.module#FeatureModule'
      }
    ];
    
  • 我假设在AppModule模板的某个地方,我有一个<router-outlet>和一个routerLink可以导航到/feature

    < / li>
  • FeatureModule中,我们仍然必须生成要在其中导航时显示的组件:ng generate component feature/start
  • 要使新的StartComponent成为路由到FeatureModule时显示的初始组件,我将调整FeatureRoutingModule中的路由:

    const routes: Routes = [{
      path: '',
      component: StartComponent
    }];
    
  • 现在,我要使用在FooService内添加到SharedModule的{​​{1}}。所以我把它注入那里。

    StartComponent
  • export class StartComponent implements OnInit { constructor(private foo: FooService) { } ngOnInit() { } }

  • 导航到ng serve并看到运行时错误!这就是我的预期,因为我没有将FeatureModule导入SharedModule中,因此注入器不知道FeatureModule
  • 到目前为止,到目前为止,我们来谈谈我的问题的重点:
  • 我将再创建一个模块,该模块不会延迟加载,该模块将成为FooService。为了保持CoreModule尽可能整洁,我将在AppModule中实现初始应用。 CoreModule
  • 当然,我们在ng generate module core中也需要一些组件:CoreModule
  • 现在,我还想在新的ng generate component core/core-main中使用FooService。因此,我们也将其注入其中:

    CoreMainComponent
  • 这一次,我不会忘记将export class CoreMainComponent implements OnInit { constructor(private foo: FooService) { } ngOnInit() { } } 导入我的SharedModule中。但是请记住,我仍然忘记并且没有在CoreModule中导入SharedModule。当然,我必须在某个地方使用FeatureModule,所以我将其导出。这是新的CoreMainComponent装饰:

    CoreModule
  • 还将@NgModule({ imports: [ CommonModule, SharedModule ], declarations: [CoreMainComponent], exports: [CoreMainComponent] }) export class CoreModule { } 导入CoreModule并在AppModule的模板中添加AppModule

  • <app-core-main></app-core-main>
  • 我的期望:一旦单击链接以延迟加载并导航到我的ng serve,我仍然会遇到运行时错误。 FeatureModule导入CoreModule,但SharedModule不导入。但是在两个模块中,都使用FeatureModule
  • 实际上,它可以工作。我可以使用功能模块中的组件,而不会出现任何错误。因此,即使在FooService中,注入器似乎也知道FooService,尽管我没有将其导入。我本来以为会失败
  • 有人可以帮我理解为什么会起作用吗?

1 个答案:

答案 0 :(得分:1)

只要您在AppModule中导入任何非延迟加载的模块,然后该非延迟加载的模块的服务,这就是应该的工作方式< / strong>在整个应用程序中都可用。

除此之外,Angular父级和子级模块中的 共享相同的Injector! 。但是对于FeatureModule延迟加载的模块),它们具有自己的注入器,因此延迟加载的模块中提供的任何服务仅适用于该模块。

在您的情况下,您可以说CoreModuleAppModule的子模块,而SharedModuleCoreModule的子模块,因为两者都是非惰性的加载的模块,这就是FooService自动在FeatureModule中可用的原因。