【问题标题】:Angular dynamic DI with string token带字符串标记的角动态 DI
【发布时间】:2018-10-25 14:49:57
【问题描述】:

似乎 Angular 6 (4+?) 要求令牌 objects 是唯一的,以便 DI 工作。然而,我想使用一个动态令牌,由模板 html 代码提供,这将允许我的新指令按名称解析服务。

目前代码:

this.service = this.injector.get(new InjectionToken<IServiceRef>(tokenName));

失败:

Error: StaticInjectorError(AppModule)[InjectionToken the_token_name]: 

当我用旧的(角度 4)Injector.get 函数替换我的代码时,它可以正常工作,因为注入器比较名称(并且我确实以该名称在视图中提供服务......)。然而,有了新的 DI,我无法实现我想要的。

那么,如何应对呢?

【问题讨论】:

  • 但是这些服务也是硬编码的。那么为什么不对你的令牌进行硬编码呢?
  • 恒定的硬编码字符串(这是我所拥有的)是不够的。必须使用单个令牌 OBJECT 才能使 DI 机制工作

标签: angular dependency-injection angular-di


【解决方案1】:

您必须为您的令牌使用全局存储对象。我建议你使用地图。

export const tokens: Map<string, InjectionToken<IServiceRef>> = new Map();
tokens.set('tokenName', new InjectionToken<IServiceRef>('tokenName'));

您必须使用地图对象来声明提供者。

@NgModule({
     providers: [
          {provide: tokens.get('tokenName'), useValue: new Service()}
     ]
 );

您现在可以通过字符串值查找令牌。

this.service = this.injector.get(tokens.get(the_token_name));

我不知道这在 Angular 6 中发生了变化,但我记得文档说令牌是按值引用的。这意味着 DI 使用=== 来匹配依赖项。

如果按令牌名称匹配,则会在 DI 中发生冲突。许多库声明一个“文档”标记作为示例。所以你不想使用字符串名称。因为碰撞极难发现和修复。

【讨论】:

  • 不错的解决方案!我之前尝试过,但我错过了提供:部分...
  • 很棒的解决方案!能够实现跨各种模块的多个服务实现使用的通用接口。 @Reactgular,你救了我的命 ;-)
  • 发布了一个答案,展示了我如何通过您的解决方案解决我的问题here
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-20
相关资源
最近更新 更多