Thanks to @Günter Zöchbauer and link he has posted in one of the comments and the answer here I have found a solution:
I decided to use ngComponentOutlet that as docs says:
NgComponentOutlet provides a declarative approach for dynamic component creation
First I made a dynamic component:
import {Component, OnChanges, OnInit, Input, NgModule,NgModuleFactory,Compiler, SimpleChanges} from '@angular/core';
import { SharedModule } from './shared.module';
@Component({
selector: 'dynamic',
template: `<ng-container *ngComponentOutlet="dynamicComponent;ngModuleFactory: dynamicModule;"></ng-container>`
})
export class DynamicComponent {
dynamicComponent: any;
dynamicModule : NgModuleFactory<any>;
@Input('html') html: string;
constructor(private compiler: Compiler) {}
ngOnChanges(changes: SimpleChanges) {
if (changes['html'] && !changes['html'].isFirstChange()) {
this.dynamicComponent = this.createNewComponent(this.html);
this.dynamicModule = this.compiler.compileModuleSync(this.createComponentModule(this.dynamicComponent));
}
}
ngOnInit() {
this.dynamicComponent = this.createNewComponent(this.html);
this.dynamicModule = this.compiler.compileModuleSync(this.createComponentModule(this.dynamicComponent));
}
protected createComponentModule(componentType: any) {
@NgModule({
imports : [SharedModule],
declarations: [
componentType
],
entryComponents: [ componentType ]
})
class RuntimeComponentModule {
}
// a module for just this Type
return RuntimeComponentModule;
}
protected createNewComponent(template: string) {
@Component({
selector: 'dynamic-component',
template: template ? template: '<div></div>'
})
class MyDynamicComponent {}
return MyDynamicComponent;
}
}
Then I imported my dynamic component to my module:
import { DynamicComponent } from './dynamic-item/dynamic-item';
@NgModule({
declarations: [
...
DynamicComponent,
],
exports: [
...
DynamicComponent,
]
})
export class ComponentsModule { }
No i could use my dynamic component with any dynamically loaded html template inside:
<dynamic [html]="dynamicHtml"></dynamic>
where dynamicHtml
can by any html containing any existing component / directive / etc.:
dynamicHtml: string = "<p group_id>A</p>";
What is worth to notice is that this approach requires JIT compiler so while developing everything works fine, but after compilation with AoT I get an error when running:
ERROR Error: Runtime compiler is not loaded
Under the original question in one of the comments @Günter Zöchbauer has posted a link to feature request tht can solve that problem. For now if you want to use this approach do not use AoT compilation.