I'm trying to make a document generation tool in angular and I'm hitting a challenge with how I would allow a user to dynamically create content.
My components I want to create could have arbitrary models and behavior so I don't think I could use a shared component.
The components I'm describing would not exist at compile time.
I see some documentation for rendering dynamic components. However it mentions that you must list the "dynamic" component in entryComponents
in the ngModule
. which will not work for my scenario.
Is there another mechanism to get this effect?
You can create a module and a component on-the-fly, apply decorators to it and then compile it all. Then you will be able to access the compiled components:
@ViewChild('vc', {read: ViewContainerRef}) vc: ViewContainerRef;
constructor(private _compiler: Compiler,
private _injector: Injector,
private _m: NgModuleRef<any>) {
}
ngAfterViewInit() {
const template = '<span>generated on the fly: {{name}}</span>';
const tmpCmp = Component({template: template})(class {
});
const tmpModule = NgModule({declarations: [tmpCmp]})(class {
});
this._compiler.compileModuleAndAllComponentsAsync(tmpModule)
.then((factories) => {
const f = factories.componentFactories[0];
const cmpRef = f.create(this._injector, [], null, this._m);
cmpRef.instance.name = 'dynamic';
this.vc.insert(cmpRef.hostView);
})
}
For this approach to work you need to bring compiler to the runtime. For more details on dynamic components read the article:
- Here is what you need to know about dynamic components in Angular