I would like to inject a component through an innerHTML.
<article class="card-body">
<div class="body-container" [innerHTML]="bodyCard.content"></div>
</article>
@Input() bodyCard: BodyCard = {
content: `
<p class="body-content">
some text
// then the component
<ftn-tooltip></ftn-tooltip>
</p>
I have no error but the component does not display. I checked with ComponentFactoryResolver but it seems to work only with ng-template and not with a HTML tag such as a DIV.
Any reccomendation please ?
Generally you can inject a component using componentFactoryResolver
A directive like
@Directive({
selector: '[adHost]',
})
export class AdDirective {
constructor(public viewContainerRef: ViewContainerRef) { }
}
Allow get the "ViewContainerRef" of a ng-template or div. adding in a html tag
<ng-template adHost></ng-template>
Then we can get the "ng-template" and his ViewContainerRef using ViewChild
@ViewChild(AdDirective, {static: true}) adHost!: AdDirective;
And in any moment use like
//get the component -see that we put the Class of component
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(MyComponent);
//see we get the viewContainerRef of the "directive"
const viewContainerRef = this.adHost.viewContainerRef;
viewContainerRef.clear();
const componentRef = viewContainerRef.createComponent<MyComponent>(componentFactory);
Some authores, like Dave Rivera prefer to have a service. It's the same idea but its a bit transparent because all the responsability of create the component is translatate to the service
export class LoaderService {
viewContainerRef:ViewContainerRef;
constructor(private factoryResolver:ComponentFactoryResolver) {
}
setViewContainerRef(viewContainerRef) {
this.viewContainerRef = viewContainerRef
}
addHelloComponent() {
const factory = this.factoryResolver
.resolveComponentFactory(HelloComponent)
this.viewContainerRef.clear();
const componentRef = this.viewContainerRef.createComponent<HelloComponent>(factory);
return componentRef.instance;
}}
Now, we can inject the service, call the function AddHelloComponent passing a ViewContainerRef in any moment if we has a constructor
constructor(private loaderService:LoaderService){}
//and in any moment
this.loaderService.addHelloComponent(this.adHost.viewContainerRef);
we can join the two concepts and create a directive like
@Directive({
selector: '[adHello]',
})
export class AdHelloDirective implements OnInit {
@Input('adHello') name
constructor(public viewContainerRef: ViewContainerRef,private factoryResolver:ComponentFactoryResolver) { }
ngOnInit(){
const factory = this.factoryResolver
.resolveComponentFactory(HelloComponent)
this.viewContainerRef.clear();
const componentRef = this.viewContainerRef.createComponent<HelloComponent>(factory);
componentRef.instance.name=this.name;
}
}
that it's used like
<ng-template adHello="new from adhelo"></ng-template>
See stackblitz
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With