Home > other >  Dynamically load component of a generic type in Angular 13
Dynamically load component of a generic type in Angular 13

Time:11-18

I have a component that need to dynamically load another component in its template, so I followed this tutorial dynamic-component-loader, so basically my component looks like

@Component(
selector: 'appPopout',
template: `
    <div> ...some stuff here... </div>
    <ng-template appTableHost></ng-template>
`
)
export class PopoutComponent<T extends PopoutTable> implements OnInit {
   

@ViewChild(TableHostDirective, {static: true}) tableHost!: TableHostDirective;

constructor(){}

ngOnInit(){
   const viewContainerRef = this.tableHost.viewContainerRef;
   viewVontainerRef.clear();

   const componentRef = viewContainerRef.createComponent<T>();
}

}

I'm stuck here and don't know how to proceed, the createComponent method requires a Type<T> as a parameter, how can I pass one?

Any help will be much appreciated

CodePudding user response:

You have to pass class of the component, and you may not refer to a type directly. Just do it like this:

const componentRef = viewContainerRef.createComponent(MyComponentClass);

CodePudding user response:

The T refers a class or in this case an interface, when you use an interface it could be implemented on different classes and it could help you with Polymorphism. Based on the Angular documentation example, you could put something like this.

viewContainerRef.createComponent<AdComponent>(HeroProfileComponent);

At the end of the example there is a link to live example, I recommend you go to the link and see the complete example, there you can interact with the code and make changes, for example I modified the AdBannerComponent in order to show how this example can use the interface AdComponent as a type and create the HeroProfileComponent dynamically. just do it like this:

import { HeroProfileComponent } from './hero-profile.component';
loadComponent() {
this.currentAdIndex = (this.currentAdIndex   1) % this.ads.length;
const adItem = this.ads[this.currentAdIndex];

const viewContainerRef = this.adHost.viewContainerRef;
viewContainerRef.clear();

const componentRef =
  viewContainerRef.createComponent<AdComponent>(HeroProfileComponent);
componentRef.instance.data = adItem.data;

}

Best Regards

  • Related