如何在延迟加载的模块中提供服务,并将该服务限定为延迟加载的模块及其组件?

时间:2017-03-17 15:27:23

标签: angular angular2-routing angular2-modules

在angular docs FAQ部分中,它指出,“与启动时加载的模块的提供者不同,延迟加载模块的提供者是模块范围的。” link

这里的'module-scoped'是指模块还是扩展为包含属于该模块的所有组件?

我问的原因是因为我有一个带有2个属于它的组件的延迟加载模块。我在模块中注册了一个服务,但由于某种原因,每个组件都获得了该服务的不同实例。

为了在我的延迟加载模块中提供LazyModuleService并将该服务限定为延迟加载模块及其组件,我需要更改什么?请包含所需的任何其他文件。我试图制作一个通用的例子来帮助其他可能发现这个问题的人。

延迟加载模块:

import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { Component1 } from './component1.component';
import { Component2 } from './component2.component';
import { LazyModuleService } from './lazy-module.service';

@NgModule({
  imports: [
    CommonModule,
  ],
  declarations: [
    Component1,
    Component2,
  ],
})

export class LazyLoadedModule { }

3 个答案:

答案 0 :(得分:8)

延迟加载的工作原理:

经过深入调查后,似乎问题与如何实施延迟加载有关。

在您的情况下,您的延迟加载模块实际上已经路由到其中的两个不同组件 - 这两个组件都直接公开为Router.forChild路由。但是,因此,当您导航到每个组件时,会为每个组件添加一个单独的延迟加载模块提供程序实例。

由于您实际上希望延迟加载模块中的所有组件共享其提供的服务的相同实例,因此您需要创建一个“root”组件,然后让您的两个组件成为该根组件的子组件。

似乎在延迟加载时,模块中的提供程序将添加到模块根目录中的组件的注入器中。由于你有两个“根组件”,它们每个都有不同的服务实例。

解决方案是创建一个根组件,其注入器将接收延迟加载的服务,然后可以由任何子组件共享。

答案 1 :(得分:3)

只需将LazyModuleService添加为LazyLoadedModule中的提供程序即可。您只能在该模块中的组件中使用它。

答案 2 :(得分:2)

Angular 6提供的出色内置解决方案。 如果您使用的是Angular 6+(请检查package.json以了解信息),则可以通过其他方式提供应用程序范围的服务。

您可以在@Injectable()中设置以下配置,而不是向AppModule中的provider []数组添加服务类:

@Injectable({providedIn: 'root'})
export class MyService { ... }

这与以下内容完全相同:

export class MyService { ... }

import { MyService } from './path/to/my.service';

@NgModule({
    ...
    providers: [MyService]
})
export class MyService { ... }

使用这种新语法是完全可选的,传统语法(使用provider [])仍然可以使用。但是,“新语法”确实提供了一个优点:Angular可以在后台(延迟)加载服务,并且可以自动删除冗余代码。这可以带来更好的性能和加载速度-尽管实际上只有在更大的服务和应用中才能使用。

来源:Udemy