Cómo crear dinámicamente un componente en Angular
En este artículo, aprenderemos a crear un componente de forma dinámica. Es posible que deba cargar un componente dinámicamente en varios escenarios, como desea mostrar una ventana emergente, modal, etc.
Supongamos que tenemos un componente como el que se enumera a continuación, que cargaremos dinámicamente.
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-message',
template: `<h2>{{message}}</h2>
`
})
export class MessageComponent {
@Input() message: string;
}
Para cargar MessageComponent dinámicamente, necesita un contenedor. Digamos que queremos cargar MessageComponent dentro de AppComponent. Necesitamos un elemento contenedor en AppComponent.
Template of AppComponent is as below:
<div style="text-align:center">
<h1>
Welcome to {{ title }}!
</h1>
<template #messagecontainer>
</template>
</div>
Como ves eso, tenemos una plantilla de punto de entrada o una plantilla de contenedor en la que cargaremos MessageComponent dinámicamente.
En AppComponent, necesitamos importar lo siguiente:
- ViewChild, ViewContainerRef y ComponentFactoryResolver de @angular/core
- ComponentRef y ComponentFactory desde @angular/core
- MessageComponent de message.component
Después de importar las cosas requeridas, AppComponnet se verá como la siguiente lista:
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';
}
Podemos acceder a la plantilla como ViewChild dentro de la clase Component. La plantilla es un contenedor en el que queremos cargar el componente dinámicamente. Por lo tanto, tenemos que acceder al templo como ViewConatinerRef.
ViewContainerRef representa el contenedor donde se pueden adjuntar una o más vistas. Esto puede contener dos tipos de vistas.
- Host Views
- Embedded Views
Las vistas de host se crean creando instancias de un componente mediante createComponent y las vistas incrustadas se crean mediante la creación de instancias de una plantilla incrustada mediante createEmbeddedView. Usaremos vistas de host para cargar dinámicamente MessageComponent.
Vamos a crear una variable llamada entrada que hará referencia al elemento de la plantilla. Además, hemos inyectado servicios ComponentFactoryResolver a la clase de componente, que serán necesarios para cargar dinámicamente el componente.
export class AppComponent {
title = 'app';
@ViewChild('messagecontainer', { read: ViewContainerRef }) entry: ViewContainerRef;
constructor(private resolver: ComponentFactoryResolver) { }
}
Tenga en cuenta que la variable de entrada que es la referencia del elemento de plantilla tiene API para crear componentes, destruir componentes, etc.
Ahora, para crear un componente, vamos a crear una función. Dentro de la función, necesitamos realizar las siguientes tareas,
- Limpiar el contenedor
- Creación de un generador para MessageComponent
- Crear componente usando la fábrica
- Pase el valor de las propiedades de @Input mediante el método de instancia de referencia de componentes
Juntando todo, la función createComponent se verá como la siguiente lista:
createComponent(message) {
this.entry.clear();
const factory = this.resolver.resolveComponentFactory(MessageComponent);
const componentRef = this.entry.createComponent(factory);
componentRef.instance.message = message;
}
Podemos llamar a la función createComponent en el evento de clic del botón. Pongamos dos botones en la plantilla y llamemos a la función createComponent al hacer clic en los botones.
<div style="text-align:center">
<h1>
Welcome to {{ title }}!
</h1>
<button (click)="createComponent('Welcome Foo ! ')">Welcome</button>
<button (click)="createComponent('Foo Again ?')">Not Welcome</button>
<br />
<template #messagecontainer>
</template>
</div>
En la salida, puede ver que el componente se carga dinámicamente al hacer clic en el botón.

Al hacer clic en los botones, el componente se volverá a cargar con un mensaje diferente. Puede destruir un componente utilizando el método destroy en componentRef.
destroyComponent() {
this.componentRef.destroy();
}
Puede destruir el componente cargado dinámicamente llamando manualmente a la función o colocarlo dentro del enlace del ciclo de vida ngOnDestroy() del componente, de modo que cuando el componente host se destruya automáticamente, el componente cargado dinámicamente también destruirá.
Poniendo todo junto, AppComponent se verá como se muestra a continuación:
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';
componentRef: any;
@ViewChild('messagecontainer', { read: ViewContainerRef }) entry: ViewContainerRef;
constructor(private resolver: ComponentFactoryResolver) { }
createComponent(message) {
this.entry.clear();
const factory = this.resolver.resolveComponentFactory(MessageComponent);
this.componentRef = this.entry.createComponent(factory);
this.componentRef.instance.message = message;
}
destroyComponent() {
this.componentRef.destroy();
}
}
En este punto, al ejecutar la aplicación, obtendrá un error porque no hemos establecido entryComponents en AppModule. Podemos configurarlo como se muestra en la lista a continuación:
import { AppComponent } from './app.component';
import { MessageComponent } from './message.component';
@NgModule({
declarations: [
AppComponent, MessageComponent
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent],
entryComponents: [MessageComponent]
})
export class AppModule { }
Esto es todo lo que necesita hacer para cargar un componente dinámicamente en Angular.
¿Te gusta esta publicación?
¡Y ahí lo tienes! Si te gusta esta publicación, dale me gusta y compártela. Además, si no ha realizadoInfragistics Ignite UI for Angular, ¡asegúrese de hacerlo! Tienen 50+ componentes de Angular basados en materiales para ayudarlo a codificar aplicaciones web rápidas más rápido.