Angular2 - Dynamic components in content received by API

后端 未结 3 631
礼貌的吻别
礼貌的吻别 2021-01-22 17:04

I have a component . The content for this component is received by API and it contains another components .

The question is, how to render the child component. When I pu

相关标签:
3条回答
  • 2021-01-22 17:34

    Using other answers and Gunter's hints here is what works for me:

    @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);
       });
     }
    }
    
    0 讨论(0)
  • 2021-01-22 17:41

    Even when you use the safeHtml pipe mentioned in @laser's answer, Angular doesn't process HTML added using innerHTML. It is just added as HTML and not processed any furter - no components or directives are created, no data binding or event binding will happen.

    What you can do is to create a component at runtime with your HTML as template content and then add this component dynamically using ViewContainerRef.createComponent() and resolveComponentFactory

    See also Equivalent of $compile in Angular 2

    0 讨论(0)
  • 2021-01-22 17:42

    Here is good solution with safeHtml directive: https://github.com/ngx-translate/core/issues/354

    You create a directive:

    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);
        }
      }
    }
    

    and use it as following: <div [safeHtml]="'HELLO' | translate"></div>

    0 讨论(0)
提交回复
热议问题