angluar动态生成html组件

骑驴找蚂蚁 · 2021年04月02日 · 阅读 51

在使用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);  
 });
}

渲染结果

查看代码

关于作者

全栈工程师

文章被阅读 118.3k
获赞 11