You can read full article on the Infragistics blog
In this article, we will learn to create a component dynamically. You may need to load a component dynamically in various scenarios such as want to show a popup modal etc.
Let us assume that, we have a component as listed below, which we will load dynamically.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Component, Input } from '@angular/core'; | |
@Component({ | |
selector: 'app-message', | |
template: `<h2>{{message}}</h2> | |
` | |
}) | |
export class MessageComponent { | |
@Input() message: string; | |
} |
To load MessageComponent dynamically you need a container. Let us say that we want to load MessageComponent inside AppComponent. We need a container element in the AppComponent.
Template of AppComponent is as below:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div style="text-align:center"> | |
<h1> | |
Welcome to {{ title }}! | |
</h1> | |
<template #messagecontainer> | |
</template> | |
</div> |
As you see that, we have an entry point template or a container template in which we will load MessageComponent dynamically.
In the AppComponent, we need to import following:
- ViewChild, ViewContainerRef, and ComponentFactoryResolver from @angular/core
- ComponentRef and ComponentFactory from @angular/core
- MessageComponent from message.component
After importing required things, AppComponnet will look like following listing:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
Component, | |
ViewChild, | |
ViewContainerRef, | |
ComponentFactoryResolver, | |
ComponentRef, | |
ComponentFactory | |
} from '@angular/core'; | |
import { MessageComponent } from './message.component'; | |
@Component({ | |
selector: 'app-root', | |
templateUrl: './app.component.html' | |
}) | |
export class AppComponent { | |
title = 'app'; | |
} |
We can access template as the ViewChild inside the Component class. Template is a container in which, we want to load the component dynamically. Therefore, we have to access temple as ViewConatinerRef.
ViewContainerRef represents container where one or more view can be attached. This can contain two types of views.
- Host Views
- Embedded Views
Host Views are created by instantiating a component using createComponent and Embedded Views are created by instantiating an Embedded Template using createEmbeddedView. We will use Host Views to dynamically load MessageComponent.
Let us create a variable called entry which will refer template element. In addition, we have injected ComponentFactoryResolver services to component class, which will be needed to dynamically load the component.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export class AppComponent { | |
title = 'app'; | |
@ViewChild('messagecontainer', { read: ViewContainerRef }) entry: ViewContainerRef; | |
constructor(private resolver: ComponentFactoryResolver) { } | |
} |
Keep in mind that entry variable which is reference of template element has API to create components, destroy components etc.
Now to create component, let us create a function. Inside the function, we need to perform following tasks,
- Clear the container
- Create a factory for MessageComponent
- Create component using the factory
- Pass value for @Input properties using component reference instance method
Putting everything, together createComponent function will look like listing below:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
createComponent(message) { | |
this.entry.clear(); | |
const factory = this.resolver.resolveComponentFactory(MessageComponent); | |
const componentRef = this.entry.createComponent(factory); | |
componentRef.instance.message = message; | |
} |
We can call createComponent function on click event of the button.
Leave a Reply