【问题标题】:Angular2 - Dynamic components in content received by APIAngular2 - API 接收的内容中的动态组件
【发布时间】:2017-02-15 19:17:36
【问题描述】:

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

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

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

【问题讨论】:

标签: angular


【解决方案1】:

在这里使用其他答案和 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);
   });
 }
}

【讨论】:

    【解决方案2】:

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

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

    另见Equivalent of $compile in Angular 2

    【讨论】:

    • 我不确定如何添加组件。内容中的任何位置都可能有一个或多个 。我尝试创建一个组件并将其添加到
      中,并且效果很好。但我的问题有点复杂。
    • 您只需要在运行时创建一个组件,就像上面链接的答案中解释的那样,它包含您的整个 HTML,包括组件选择器。创建组件时,子组件也会自动创建(如果它们都注册在模块directives: [...]参数中)。然后你只需要自己添加动态创建的组件。
    【解决方案3】:

    这里是使用 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);
        }
      }
    }
    

    并按如下方式使用:&lt;div [safeHtml]="'HELLO' | translate"&gt;&lt;/div&gt;

    【讨论】:

      猜你喜欢
      相关资源
      最近更新 更多
      热门标签