Hello I have a component that acts as Component Factory for a collection of UI components I have.
in order to show a component from my collection I do like this:
<div myComponentFactory elementType="simpleText" data="my simple text here"></div>
in which my myComponenFactory loads dynamically the requested component (in this example "simpleText" component) and displays it.
the result of the final dom is like this:
<div myComponentFactory>
<div simpleText>
my simple text here
</div>
</div>
however, what I want to achieve is something simpler, such as:
<div myComponentFactory>
my simple text here
</div>
This is what I'm doing right now. I'm using @ViewChild and loading the requested component inside the template of the factory component:
my-component-factory.component.ts
@Component({
selector: '[myComponentFactory]',
template: '<ng-container #elementToBind></ng-container>',
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class MyComponentFactoryCompnent implements AfterViewInit {
@Input() elementType: string;
@Input() data: any;
@ViewChild('elementToBind', {read: ViewContainerRef}) private elementToBind: ViewContainerRef;
ngAfterViewInit(): void {
// switch case with all the components available
switch (this.elementType) {
case 'simpleText':
// this loads dynamically the "simpleText" component
return defer(() => import('path/to/simpleText.module'))
.pipe(
map((el) => {
const module = el.SimpleTextModule;
const componentModule = this.compiler.compileModuleAndAllComponentsSync(module);
const factory = componentModule.componentFactories.find(c => c.componentType === SimpleTextComponent);
return factory;
}),
map((factory) => {
const template: any = this.elementToBind.createComponent(factory);
template.instance.data = this.data;
return template;
})
);
//////////////////////////////////
// other components switch case //
//////////////////////////////////
}
}
}
simple-text.component.ts
@Component({
selector: '[simple-text]',
templateUrl: './simple-text.component.html',
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SimpleTextComponent{
@Input() data: any
}
simple-text.component.html
{{data}}
Is it possible to substitute the original host container of my componentFactory? I've tried also creating a directiveFactory instead of a componentFactory, however, the result is the same.
Thanks a lot for your support!!
Marco