angular - Angular 11 DI 用于动态编译的组件
问题描述
使用 JitCompilerFactory 并在运行时编译组件有效(例如,请参见此处: https ://stackoverflow.com/a/67122569/15816951 )但注入动态组件不会:
// (1) define Component metadata
const metadata = new Component({
selector: "dynamic-selector",
template: "This is template: {{text}}" // <---- Interpolation: works
});
// (2) define Component class and decorate
const compClass = class DynamicComponent {
text: string = 'from'; // <---- Interpolation: works
constructor(public s: Service1) { } // <---- Trying to inject a service: FAILS
};
const decoratedComp = Component(metadata)(compClass);
// (3) define Module class and decorate
const decoratedModule = NgModule({
imports: [...],
declarations: [decoratedCmp]
})(class DynamicModule { })
// (4 )compile Module and grab the Component Factory
const module = compiler.compileModuleAndAllComponentsAsync(decoratedModule);
const factory = module.componentFactories.find(x => x.componentType === decoratedCmp);
// (5) render the component using Component Factory
someViewContainerRef.createComponent(factory);
如果没有组件类构造函数中的 DI(上面的#2),一切都很好,但尝试注入原因:
core.js:6210 错误错误:未捕获(承诺中):错误:此构造函数与 Angular 依赖注入不兼容,因为它在参数列表索引 0 处的依赖无效。
如果依赖类型是像字符串这样的原始类型,或者如果此类的祖先缺少 Angular 装饰器,则可能会发生这种情况。
请检查 1) 索引 0 处的参数类型是否正确,以及 2) 为此类及其祖先定义了正确的 Angular 装饰器。错误:此构造函数与 Angular 依赖注入不兼容,因为它在参数列表索引 0 处的依赖无效。如果依赖类型是像字符串这样的原始类型,或者如果此类的祖先缺少 Angular 装饰器,则可能会发生这种情况。
我尝试根据 Angular 团队对 Angular 9 的回答添加core-js/es/reflect
和reflect-metadata
加入: https ://github.com/angular/angular/issues/35908 (使用 AoT 编译的 Ivy 项目中的 JIT 时出现 DI 错误)。polyfills.ts
我应该怎么做才能使 DI 为 Angular 11 中的动态组件工作?
解决方案
回答我的问题,以防有人追求同样的事情。感谢那些在 Angular 问题跟踪器上回复的人:https ://github.com/angular/angular/issues/41933
DI 失败是因为 TS 编译早于我们在运行时创建组件类的时间,并且 Angular 没有可用于构造函数的元数据信息。你可以:
手动提供注入元数据,例如:
(cmpClass as any).ctorParameters = () => [ {type: Service1 }];
或者添加一个装饰器并在 IIFE 中调用它,例如:
export function Annotate() {
return klass => klass;
}
const cmpClass = (() => {
@Annotate()
class DynamicComponent {
text: string = "Text";
constructor(public s: Service1) {
console.log(s);
}
handle() {
this.text = "Event handler works!";
}
}
return DynamicComponent;
})();
推荐阅读
- php - JSON by POST 从 Python 到 PHP - 收到“null”返回
- typescript - 在打字稿中导入库时导入variableName vs const variableName
- ios - Xcode 10 NavigationBar 图标未出现在某些设备上
- java - RecyclerView 内的 CardView 在展开时没有调整到正确的高度
- python - 为什么我需要 rreverse 函数的两个条件分支?
- scala - ClassTags 是如何在 Scala 中可用的?
- java - 单个 Java 应用程序中的多个 DB 连接
- apache - 如果 URL 包含参数,htaccess 重定向到基本 URL
- android - 如何知道我在运行时在 editText 中写了什么?
- r - htmlTemplate / JqueryLayout 中的 R rhandsonetable 不起作用