【问题标题】:Provide custom injector to dynamically created external + AOT-compiled component为动态创建的外部 + AOT 编译的组件提供自定义注入器
【发布时间】:2020-02-14 15:55:02
【问题描述】:

我们正在开发一个小部件风格的系统,我们希望使用 Angular 8(没有 Ivy)提供 AOT 编译的组件,这些组件通过 SystemJS 加载然后呈现。为此,我们基本上关注alexzuza's approach。构建、捆绑、导入和渲染组件工作正常。

但是,我现在想为正在创建的组件提供一个自定义注入器。在我看来,这应该很简单

const injector = Injector.create({
    parent: this.injector,
    providers: [
        { provide: MY_TOKEN, useValue: 42 },
    ],
});

const compRef = this.container.createComponent(compFactory, 0, injector);

// Both of these work
console.log(injector.get(MY_TOKEN)); // 42
console.log(compRef.injector.get(MY_TOKEN)); // 42

但是,如果我们更改插件以注入此令牌:

constructor(@Inject(MY_TOKEN) private value: number) {}

…我们只是得到一个错误,因为找不到令牌:

ERROR NullInjectorError: StaticInjectorError(…)[o -> InjectionToken MY_TOKEN]


是否有关于 AOT 编译组件的特定内容阻止了它的工作?检查捆绑包的所有内容都符合我的预期,并且注入令牌中不存在名称错误或类似问题。

如何正确地为来自外部资源的组件提供自定义注入器?

【问题讨论】:

  • 您可以尝试使用string 作为令牌吗? { provide: 'MY_TOKEN', useValue: 42 } 然后constructor(@Inject('MY_TOKEN') private value: number)
  • @yurzui 字符串作为令牌似乎确实有效。知道为什么会这样吗?是否有办法使用适当的令牌?
  • @yurzui 现在我们可以做export MY_TOKEN: InjectionToken<…> = "MY_TOKEN" as any;,它从使用方面隐藏了黑客,但如果能正确解决这个问题会很好。
  • 它不适用于属性令牌,因为您的令牌来自不同的物理位置,Angular 使用 instanceof 来检查令牌
  • 您可以使用模块之间共享的令牌

标签: angular


【解决方案1】:

在 Angular 中为提供者使用令牌时的主要警告是,我们在提供者中声明并在类中注入的令牌必须从同一个物理位置导入。一个例外是字符串标记。

这意味着如果您在一个 js 文件中有 const MY_TOKEN = new InjectionToken('MY TOKEN'); 并且在另一个文件中有相同的定义,那么如果提供和注入不同的令牌,您可能会遇到这个问题。

因此,您的解决方案是使用字符串作为标记或使用捆绑包之间共享的标记

【讨论】:

    猜你喜欢
    • 2017-07-21
    • 2017-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-22
    • 2021-03-08
    相关资源
    最近更新 更多