【问题标题】:Inject a service into all component of module将服务注入到模块的所有组件中
【发布时间】:2019-11-03 02:24:31
【问题描述】:

我有一个由一个组件和一堆子组件组成的模块。还有一个专门针对这个模块的服务。

我不确定是否了解满足我需求的注射机制。 我想要做的是将服务注入所有子组件。

当我将带有提供程序的服务注入组件时,没关系,但我想在模块级别设置提供程序。

模块

import { NgModule } from '@angular/core';

import { ChangeUserComponent } from './change-user.component';
import { ChangeUserSidebarComponent } from './sidebar/sidebar.component';
import { ChangeUserUserListComponent } from './user-list/user-list.component';

import { ChangeUserService } from './change-user.service';

@NgModule({
    declarations: [
        ChangeUserComponent,
        ChangeUserUserListComponent,
        ChangeUserSidebarComponent
    ], 
    providers      : [
        ChangeUserService // <-- when i set that it's not working
    ],
    exports     : [
        ChangeUserComponent
    ]
})

export class ChangeUserModule
{
}

子组件

import { Component, OnDestroy, OnInit } from '@angular/core';
import { ChangeUserService } from '../change-user.service';

@Component({
    selector   : 'change-user-sidebar',
    templateUrl: './sidebar.component.html',
    styleUrls  : ['./sidebar.component.scss'],
    //providers:  [ ChangeUserService ] // <-- with that the service is correctly injected
})
export class ChangeUserSidebarComponent
{

  public activeNode: any;

    constructor(
      private _changeUserService: ChangeUserService
    )
    {
    }
}

服务

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable()
export class ChangeUserService 
{
    constructor(
        private _http: HttpClient
    ){}
}

当我在组件级别设置 Provider 但我想在模块级别设置它时,服务被正确注入。

编辑:当我在组件级别设置关键字提供者时:一切正常

何时在模块级别设置关键字提供者:

错误:未捕获(承诺中):NullInjectorError:StaticInjectorError(AppModule)[ChangeUserSidebarComponent -> ChangeUserService]: StaticInjectorError(平台:核心)[ChangeUserSidebarComponent -> ChangeUserService]: NullInjectorError: 没有 ChangeUserService 的提供者!

有没有办法做到这一点?我错过了什么吗?

【问题讨论】:

  • 有问题吗?您的模块 sn-p 是正确的,这就是您在整个应用程序上注册单例提供程序的方式。如果遇到错误,您必须向我们展示具体错误。
  • 注入是在构造函数中完成的,而不是在提供者部分。它应该可以按您的意愿工作。什么错误?
  • 是的,当我在模块级别设置提供程序时,编译器喊,我已经编辑了问题。我不想为整个应用程序注册它(在根目录中提供可注入?),但只是为了模块和该模块导入的所有组件(在示例中为 ChangeUserComponent、ChangeUserUserListComponent 和 ChangeUserSidebarComponent)。目标是仅在模块级别为所有导入的组件注册服务,而不是在导入组件的每个 @Component 块中设置关键字提供程序。
  • 除非它是延迟加载的模块,否则您不能将提供程序限定为模块。如果可以访问该类型,任何东西都可以注入提供者。
  • 再一次,你的代码没有问题,它不应该产生那个错误,你能在stackblitz?上创建一个最小的问题重现

标签: angular typescript


【解决方案1】:

我不会把任何人关在地牢里做那件事 ;-) !

最后我决定遵循第一个解决方案并将服务 Injectable for Root。不想做复杂的事情来避免可能/不应该发生的事情(即:将服务用于另一个组件,而不是专门用于此服务的组件)。

最初我真正想做的是将服务范围仅限于它的模块,并将其提供给模块的子组件。

将服务放入 Root 允许我共享该服务,我将假设该服务不应被应用程序的其他部分使用。

无论如何,我仍然不知道为什么将服务设置为模块在我的上下文中不起作用。

【讨论】:

    【解决方案2】:

    嗯,这很有趣。

    在组件级别你可以有一个服务注入(所以你可以直接在每个子组件中注入服务,但这不仅麻烦,而且每个组件都会有它的新服务实例)

    但如果你把我关在一个地牢里,并说无论如何都要这样做,我就会这样做。我会延迟加载该模块。

    解释:

    1. 我们有两个提供相同服务的模块(AppModule 和 LazyModule)。
    2. 由于我们的第二个模块是惰性的,Angular 不知道它的存在。 .这意味着我们的 LazyModule 的 providers 数组中列出的任何服务都不可用,因为根注入器还不知道 LazyModule ......当我们激活路由时,惰性模块将被加载并创建新的注入器。想象一棵注入器树,顶部是根注入器,对于每个惰性模块,都会创建新的子注入器。
    3. 来自根注入器的所有服务都将添加到子注入器。如果根注入器和子注入器提供相同的服务,Angular 更喜欢来自子注入器的服务实例。所以每个惰性组件都会获取服务的本地实例,而不是根应用程序注入器中的实例。
    4. 因此,Lazy 将使用它自己的另一个引用,而应用程序的其余部分将拥有它

    【讨论】:

      猜你喜欢
      • 2018-09-14
      • 2019-12-26
      • 2016-02-10
      • 2020-06-08
      • 1970-01-01
      • 1970-01-01
      • 2020-07-08
      • 2015-12-02
      相关资源
      最近更新 更多