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