【问题标题】:How do I provide a service in a lazy-loaded module and have that service scoped to just the lazy-loaded module and its components?如何在延迟加载模块中提供服务并将该服务的范围限定为延迟加载模块及其组件?
【发布时间】:2017-03-17 15:27:23
【问题描述】:

在 Angular 文档的常见问题解答部分中指出,“与启动时加载的模块的提供者不同,延迟加载模块的提供者是模块范围的。”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 { }

【问题讨论】:

  • 您是否在您的惰性模块的任何组件中将 LazyModuleService 配置为提供程序?
  • 不,我没有。它只在 LazyLoaded 模块中配置。
  • 我假设这是一个错字,但您的 LazyModule 中没有 LazyModuleService 作为提供者
  • 不在这里,但在我的实际代码中,我这样做了,但它不起作用。
  • 你能不能试着让你的模块暂时不延迟加载,看看你是否仍然遇到重复服务的问题?如果模块不是延迟加载的,则绝对应该与所有组件(包括模块外的组件)共享一个实例。如果这没有发生,那么你的配置有问题,与延迟加载无关

标签: angular angular2-routing angular2-modules


【解决方案1】:

延迟加载的工作原理:

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

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

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

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

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

【讨论】:

【解决方案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

【讨论】:

  • 你自己检查过吗,对我来说这不起作用。与延迟加载机制相关的原因问题...
  • @DicBrus 这确实有效,您必须从延迟加载模块的 providers 列表中删除 MyService
【解决方案3】:

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

【讨论】:

  • 不,这不起作用。就像我在问题中所说的那样,这就是我拥有它的方式,但它不起作用。
猜你喜欢
  • 1970-01-01
  • 2018-06-19
  • 1970-01-01
  • 2018-05-22
  • 2021-07-13
  • 2017-02-22
  • 2018-04-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多