Dynamic components in Angular refer to components that are instantiated, added or removed at runtime based on certain conditions, like user interaction or other changing parameters. This allows for more flexibility in the UI and better adaptation to user requirements. Typically, Angular applications have pre-defined components in the layout, which are rendered based on the static template. However, in some cases, it is more efficient to create components dynamically, based on user input or application state.
Angular provides ComponentFactoryResolver, ViewContainerRef, and ComponentRef classes to create and manage dynamic components. Here’s a brief explanation of these classes:
1. ComponentFactoryResolver: It enables you to get the factory for creating a component of a specific type. With this factory, you can create an instance of the component.
2. ViewContainerRef: It serves as a container where the component can be attached. In other words, it provides a location in the view where you can add or remove dynamic components.
3. ComponentRef: This is the reference to the created instance of the component. You can use it to access the component properties, its instance, and its location.
Let’s go through a simple example to see how we can use the above classes to create a dynamic component in Angular.
1. First, create a simple Angular component (ExampleComponent) that we will dynamically add to our application.
import { Component } from '@angular/core';
@Component({
selector: 'example-component',
template: '<div>This is an example dynamic component!</div>',
})
export class ExampleComponent {}
2. Now, let’s create the main AppComponent, which will dynamically load the ExampleComponent when a button is clicked.
import { Component, ComponentFactoryResolver, ViewContainerRef } from '@angular/core';
import { ExampleComponent } from './example.component';
@Component({
selector: 'app-root',
template: `
<button (click)="onButtonClick()">Add Example Component</button>
<ng-container #container></ng-container>
`,
})
export class AppComponent {
constructor(
private componentFactoryResolver: ComponentFactoryResolver,
private viewContainerRef: ViewContainerRef
) {}
onButtonClick() {
const factory = this.componentFactoryResolver.resolveComponentFactory(ExampleComponent);
const componentRef = this.viewContainerRef.createComponent(factory);
}
}
In the above AppComponent code:
- We inject ComponentFactoryResolver and ViewContainerRef.
- We define a button in the template with a click listener onButtonClick().
- We use an ‘ng-container‘ element with a template reference variable (#container) as a placeholder for our ExampleComponent.
- When the button is clicked, the onButtonClick method is called.
- Inside the onButtonClick method, we get the factory for the ExampleComponent using ComponentFactoryResolver.
- We use the factory to create an instance of ExampleComponent and attach it to the view container.
Now, when we click the "Add Example Component" button in the AppComponent, a new instance of the ExampleComponent will be added to the DOM at the specified location.
Use cases for dynamic components in Angular include:
1. Dynamic loading of components based on user interaction, e.g., a popup, dialog, or tooltip.
2. Loading different components in a dashboard based on user configuration or application state.
3. Building advanced form elements with complex validation or inputs that depend on other input fields.
4. Implementing a plugin architecture, where components from different modules or third-party libraries can be loaded and displayed as needed.
5. When multi-layout components are needed, and creating a component with multiple ng-templates becomes complex.
In summary, dynamic components offer a powerful way to make Angular applications more versatile, adaptable, and extensible. By using ComponentFactoryResolver, ViewContainerRef, and ComponentRef, you can easily create, update, and manage dynamic components in your Angular app.