Angular2 - API接收的内容中的动态组件

时间:2017-02-13 23:21:21

标签: angular

我有一个组件。该组件的内容由API接收,它包含其他组件。

问题是,如何渲染子组件。当我将收到的内容放入innerHTML时,组件标签将被删除。

我检查了所有关于使用resolveComponentFactory创建组件的文章,但似乎这是一个不同的情况。

3 个答案:

答案 0 :(得分:2)

使用其他答案和Gunter的提示对我有用:

@Component({
  selector: 'blog-app',
  template: `
  <h1> Article preview </h1>
  <div #container> </div>
  `
 })

export class BlogAppComponent {

@Input() content : string;

@ViewChild('container', { read: ViewContainerRef }) container: ViewContainerRef;


 constructor (private zone : NgZone, private compiler: Compiler ) {

 }  

 private addComponent(template: string) {
    @Component({template: template})
    class TemplateComponent {}

    @NgModule({declarations: [TemplateComponent], imports: [BlogAppModule]})
    class TemplateModule {}

    const mod = this.compiler.compileModuleAndAllComponentsSync(TemplateModule);
    const factory = mod.componentFactories.find((comp) =>
      comp.componentType === TemplateComponent
    );
    const component = this.container.createComponent(factory);
 }

 ngOnChanges(changes: SimpleChanges)  {

   this.zone.run(() => {
       this.addComponent(changes['content'].currentValue);
   });
 }
}

答案 1 :(得分:1)

即使您使用@ laser的答案中提到的safeHtml管道,Angular也不会处理使用innerHTML添加的HTML。它只是作为HTML添加而不是任何进一步处理 - 没有创建任何组件或指令,也不会发生数据绑定或事件绑定。

您可以做的是在运行时使用HTML作为模板内容创建组件,然后使用ViewContainerRef.createComponent()resolveComponentFactory动态添加此组件

另见Equivalent of $compile in Angular 2

答案 2 :(得分:0)

这是使用safeHtml指令的好解决方案:https://github.com/ngx-translate/core/issues/354

您创建了一个指令:

import { Directive, ElementRef, Input, OnChanges, Sanitizer, SecurityContext,
  SimpleChanges } from '@angular/core';

// Sets the element's innerHTML to a sanitized version of [safeHtml]
@Directive({ selector: '[safeHtml]' })
export class HtmlDirective implements OnChanges {
  @Input() safeHtml: string;

  constructor(private elementRef: ElementRef, private sanitizer: Sanitizer) {}

  ngOnChanges(changes: SimpleChanges): any {
    if ('safeHtml' in changes) {
      this.elementRef.nativeElement.innerHTML =
        this.sanitizer.sanitize(SecurityContext.HTML, this.safeHtml);
    }
  }
}

并将其用作以下内容:<div [safeHtml]="'HELLO' | translate"></div>