10

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

这里的“模块范围”是指模块还是扩展为包括属于该模块的所有组件?

我问的原因是因为我有一个延迟加载的模块,其中包含 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 { }
4

3 回答 3

12

延迟加载的工作原理:

经过深入调查,似乎问题与延迟加载的实现方式有关。

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

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

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

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

于 2017-03-17T20:40:31.673 回答
2

Angular 6 提供了很棒的内置解决方案。如果您使用的是 Angular 6+(请检查您的 package.json 以找出答案),您可以以不同的方式提供应用程序范围的服务。

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

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

这与以下内容完全相同:

export class MyService { ... }

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

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

使用这种新语法是完全可选的,传统语法(使用 providers[] )仍然有效。不过,“新语法”确实提供了一个优势:Angular(在幕后)可以延迟加载服务,并且可以自动删除冗余代码。这可以带来更好的性能和加载速度——尽管这实际上只适用于更大的服务和应用程序。

来源:Udemy

于 2018-07-06T05:25:26.693 回答
0

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

于 2017-03-17T15:30:50.067 回答