Table Of Contents

骑驴找蚂蚁

全干工程师

angluar动态生成html组件

在使用angular框架时,我们有时候需要根据动态的html模板内容渲染组件。如果你是直接DomSanitizer类生成安全的html再绑定到[innerHTML]属性,当你的html包含一些angluar组件时,它是不会进行渲染的这时候我们就需要根据html内容动态创建组件渲染。

通过这种方式你就可以处理服务端返回的html或者自定义生成的html进行动态渲染。使用这种有一个弊端就是在你发布上线时(也就是build)不用使用aot方式进行构建。你必须使用以下命令去构建。

ng build --prod --aot=false --build-optimizer=false

创建组件

和正常创建组件没有什么区别,我们还是要定义ComponentModule。只是把这段代码封底装成一个函数。你也可以在组件里面定义@inputModule里面导入其它的模块。

export async function createComponentFactory(compiler: Compiler, template: string): Promise<ComponentFactory<any>> {  
// const cmpClass = class DynamicComponent {};  
@Component({  
selector: 'dynamic-selector',  
template: template,  
}) class DynamicComponent {  
@Input() settings;  
@Input() source;  
}  
// IMPORT ALL MODULES HERE!!!  
@NgModule({ imports: [  
CommonModule,  
RouterModule,  
ThemeModule,  
Ng2SmartTableModule,  
/* All other modules including components that can be use with renderer */  
],  
declarations: [DynamicComponent] })  
class DynamicHtmlModule {}  
  
const moduleWithComponentFactory = await compiler.compileModuleAndAllComponentsAsync(DynamicHtmlModule);  
return moduleWithComponentFactory.componentFactories.find(x => x.componentType === DynamicComponent);  
}  
  

这段代码就是定义一个组件模块,使用解释器编译这个模块。所以必须提供解释器类。

定义ViewContainerRef

我们需要定义一个ViewContainerRef来容器来填充组件。

<ng-template #ref></ng-template>  
  
@ViewChildren("ref", { read: ViewContainerRef}) public dynComponents: QueryList<ViewContainerRef>;  
  

调用渲染

在调用的组件中你需要注入Compiler

protected createComponent(ref: ViewContainerRef, card: {[key:string]:any}) {  
createComponentFactory(this.compiler, card["body"]).then(factory => {  
const injector = Injector.create({ providers: [], parent: ref.injector });  
const cmpRef = ref.createComponent(factory, 0, injector, []);  
if (card["type"] == "table") {  
// @ts-ignore  
cmpRef.instance.settings = card["data"]["settings"];  
cmpRef.instance.source = new LocalDataSource(card["data"]["data"]);  
}  
this.cmpRef.push(cmpRef);  
});  
}  

渲染结果


查看代码

留言