【问题标题】:Angular 6 - creating a (non root) module scoped serviceAngular 6 - 创建(非根)模块范围服务
【发布时间】:2018-10-19 08:06:08
【问题描述】:

据我所知,直到 angular 6,所有 @Ngmodule 提供程序都在根注入器上注册并在主包中提供服务,即使只有延迟加载的模块使用它们。

唯一的例外是如果我们想create a non singleton services in a component level

我想创建一个单例服务,该服务仅对特定模块(而不是根模块)可见,因此不会在主热切加载的包中提供服务。

在 Angular 6 中,模块将不再需要通过 "providers" 引用服务,而是服务现在将引用该模块。

这可以通过@Injectable 注释和provideIn 属性来完成。

我没有找到一个很好且清晰的示例来说明如何添加不是“root”的模块名称,如下所示:

@Injectable({ provideIn: <MyLocalModule>})
export class SimpleServiceForLocalUseOnly { […] }

在上面的 sn-p 中导入 LazyLoaded 模块并将其写为“MyLocalModule”会导致循环依赖的警告。 我可以通过将服务移动到其他模块来解决这个问题,但是我失去了最初的目的。

搜索参考列表:

https://blog.angular.io/version-6-of-angular-now-available-cc56b0efa7a4

https://jaxenter.com/new-angular6-143995.html

https://www.ngdevelop.tech/angular-6-features/

https://blog.ninja-squad.com/2018/05/04/what-is-new-angular-6/

http://ankitsharmablogs.com/getting-started-with-angular-6-0/

https://www.youtube.com/watch?v=Xr5l7lT--YU

【问题讨论】:

    标签: angular typescript web frontend angular6


    【解决方案1】:

    如果我们按照official docs 进行此设置,似乎存在一些关于循环依赖的问题:

    import { Injectable } from '@angular/core';
    import { HeroModule } from './hero.module';
    import { HEROES }     from './mock-heroes';
    
    @Injectable({
      // we declare that this service should be created
      // by any injector that includes HeroModule.
    
      providedIn: HeroModule,
    })
    export class HeroService {
      getHeroes() { return HEROES; }
    }
    

    您可以忽略编译器由于模块、服务和组件之间的循环依赖而引发的警告。或者,回退到 Angular 5 中使用的先前方法。

    将服务注册为延迟加载模块中的提供者,注意不要在根应用模块中导入延迟加载模块:

    @NgModule({
      imports: [
        RouterModule.forChild([{ path: '', component: LazyComponent }]),
      ],
      declarations: [
        LazyComponent
      ],
      providers: [YourServiceHere]
    })
    export class LazyLoadedModule { }
    

    【讨论】:

    • 当我这样做时,我得到:在循环依赖中检测到警告:HeroService -> HeroModule -> HeroComponent -> HeroService
    • 这可能是 Angular 库本身的问题,基本上是因为此设置需要循环导入服务、模块和组件。如果它只是一个警告并且您的应用程序正在运行,那么我认为忽略它是安全的。或者您不能使用这种方式来设置模块范围的服务。只需在延迟加载模块的 providers 数组中设置服务即可。
    • 但我最初的目的不是将此服务包含在主包中,将其添加到模块提供程序数组中会得到这个结果。
    • 你懒加载你的模块了吗?据我了解,在延迟加载模块中注册的服务也是延迟加载的。
    • 是的,这个模块是延迟加载的,并且在模块的“提供者”上注册的服务被添加到根注入器而不是延迟加载(检查你是主包,看看)。据我了解,在 Angular 6 中它已更改(在第二个链接中有一个很好的封面)。
    【解决方案2】:

    要使用较新的语法在特定模块中提供服务,您只需执行以下操作:

    import { Injectable } from "@angular/core";
    import { YourModule } from "path/to/your.module";
    
    @Injectable({
        providedIn: YourModule
    })
    export class SomeModuleScopedService {}
    

    参考:https://angular.io/guide/providers#providedin-and-ngmodules

    【讨论】:

    • 它给出了问题中提到的循环依赖警告。
    【解决方案3】:

    我通过创建一个只包含服务的中间模块来实现这一点。

    import { Injectable } from '@angular/core';
    import { HeroServiceModule } from './hero.service.module';
    
    @Injectable({
      providedIn: HeroServiceModule,
    })
    export class HeroService {
    }
    

    在那个模块中你不需要太多:

    @NgModule({
      imports: [ CommonModule ]
    })
    export class HeroServiceModule {}
    

    然后你的常规模块导入服务模块:

    @NgModule({
    ...
      imports: [
    ...
         HeroServiceModule
      ]
    })
    export class HeroModule {}
    

    然后你可以像往常一样延迟加载HeroModule。这消除了所有的循环依赖。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-22
      • 1970-01-01
      • 1970-01-01
      • 2018-08-25
      • 1970-01-01
      相关资源
      最近更新 更多