Component templates are not always fixed. An application might need to load new components at runtime.
Angular comes with its own API for loading components dynamically.
To dynamically load a component in Angular, we can Use the createComponent()
method of the ViewContainerRef
to create a component instance.
The following example shows how to build a dynamic ad banner.
The anchor directive
Before adding components, we have to define an anchor point to tell Angular where to insert components.
The ad banner uses a helper directive called AdDirective
to mark valid insertion points in the template.
import { Directive, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[adHost]',
})
export class AdDirective {
constructor(public viewContainerRef: ViewContainerRef) { }
}
AdDirective
injects ViewContainerRef
to gain access to the view container of the element that will host the dynamically added component.
In the @Directive
decorator, notice the selector name, adHost
; that’s what we will use to apply the directive to the element. The next section shows us how.
Loading components
The <ng-template>
element is where we apply the directive we just made. To apply the AdDirective
, recall the selector from ad.directive.ts
, [adHost]
. Apply that to <ng-template>
without the square brackets. Now Angular knows where to dynamically load components.
template: `
<div class="ad-banner-example">
<h3>Advertisements</h3>
<ng-template adHost></ng-template>
</div>
`
PS: The <ng-template>
element is a good choice for dynamic components because it doesn’t render any additional output.
Resolving components
export class AdBannerComponent implements OnInit, OnDestroy {
@ViewChild(AdDirective, {static: true}) adHost!: AdDirective;
ngOnInit(): void {
this.loadComponent(MyDynamicComponent);
}
loadComponent(component) {
const viewContainerRef = this.adHost.viewContainerRef;
viewContainerRef.clear();
const componentRef = viewContainerRef.createComponent(component);
//we can also pass inputs to the component using the componentRef.instance property.
// for example : componentRef.instance.data = dataInputs;
}
}
In this example, “MyDynamicComponent” is the component we want to load dynamically, and adHost
is a reference to our template where we want to load the component.
we can call the loadComponent()
method with the component we want to load dynamically as an argument. For example:
this.loadComponent(customComponent);
This will load the “customComponent
” component dynamically in the template
.