TypeScript - Angular 5 - 动态组件模板加载
在我的 Angular 5 项目中,我需要在 API 数据下载后动态创建一个组件(我里面有包含 Angular 标记的 HTML 代码——我需要在请求完成后编译它们),但我看到存在 AOT 的问题。
我尝试过使用那个主题中的解决方案 Angular 4 | 通过 innerHTML 绑定模板,组件变量不可访问(在这种情况下是 damContentRoot)(以及那个 How can I use/create dynamic template to compile dynamic Component with Angular 2.0?)
这是我当前的代码:
import {
Directive,
OnChanges,
Input,
ComponentRef,
ViewContainerRef,
Compiler,
ModuleWithComponentFactories,
Component,
NgModule,
Type
} from '@angular/core';
import {CommonModule} from '@angular/common';
import { FormsModule, ReactiveFormsModule, NgForm } from '@angular/forms';
import {JitCompilerFactory} from '@angular/platform-browser-dynamic';
@Directive({selector: '[compile]'})
export class CompileDirective implements OnChanges {
@Input()compile : string;
@Input()compileContext : any;
compRef : ComponentRef < any >;
constructor(private vcRef : ViewContainerRef, private compiler : Compiler) {}
ngOnChanges() {
if (!this.compile) {
if (this.compRef) {
this.updateProperties();
return;
}
throw Error('You forgot to provide template');
}
this
.vcRef
.clear();
this.compRef = null;
const component = this.createDynamicComponent(this.compile);
const module = this.createDynamicModule(component);
this
.compiler
.compileModuleAndAllComponentsAsync(module)
.then((moduleWithFactories : ModuleWithComponentFactories < any >) => {
let compFactory = moduleWithFactories
.componentFactories
.find(x => x.componentType === component);
this.compRef = this
.vcRef
.createComponent(compFactory);
this.updateProperties();
})
.catch(error => {
console.log(error);
});
}
updateProperties() {
for (var prop in this.compileContext) {
this.compRef.instance[prop] = this.compileContext[prop];
}
}
private createDynamicComponent(template : string) {
@Component({selector: 'custom-dynamic-component', template: template})
class CustomDynamicComponent {}
return CustomDynamicComponent;
}
private createDynamicModule(component : Type < any >) {
@NgModule({
// You might need other modules, providers, etc... Note that whatever components
// you want to be able to render dynamically must be known to this module
imports: [CommonModule, FormsModule, ReactiveFormsModule],
declarations: [component],
})
class DynamicModule {}
return DynamicModule;
}
}
<ng-container *compile="this.pageData.html; context: this"></ng-container>但是我遇到错误:ERROR 错误:运行时编译器未加载
我也尝试过使用 JitCompilterFactory,但我遇到了那里提到的错误:https://github.com/angular/angular/issues/20639。
有没有办法在 AOT 编译时动态添加组件?或者将其与 JIT 结合使用根本没有意义?
我已经阅读了关于动态组件加载的整个主题(https://blog.angularindepth.com/here-is-what-you-need-to-know-about-dynamic-components-in-angular-ac1e96167f9e),但我仍然找不到解决方案,总是出现 JitCompilerFactory 错误。
答案#1
我有带有 Angular 标记的 HTML 代码——我需要在请求完成后编译它们
你所需要的只是一个根据选择器将组件加载到动态字符串中的方法,我写的 ngx-dynamic-hooks-library 可能会有所帮助。我正是为这个目的创建它的,因为我也没有找到其他好的解决方案。
它可以在 JiT 和 Aot 模式下工作,因为它完全不依赖运行时编译器,所以你无需担心这个。在这里可以看到它的工作效果。