Como criar dinamicamente um componente no Angular
Neste artigo, aprenderemos a criar um componente dinamicamente. Pode ser necessário carregar um componente dinamicamente em vários cenários, como deseja mostrar um modal pop-up, etc.
Vamos supor que temos um componente conforme listado abaixo, que carregaremos dinamicamente.
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-message',
template: `<h2>{{message}}</h2>
`
})
export class MessageComponent {
@Input() message: string;
}
Para carregar MessageComponent dinamicamente, você precisa de um contêiner. Digamos que queremos carregar MessageComponent dentro do AppComponent. Precisamos de um elemento de contêiner no AppComponent.
Template of AppComponent is as below:
<div style="text-align:center">
<h1>
Welcome to {{ title }}!
</h1>
<template #messagecontainer>
</template>
</div>
Como você pode ver, temos um modelo de ponto de entrada ou um modelo de contêiner no qual carregaremos MessageComponent dinamicamente.
No AppComponent, precisamos importar o seguinte:
- ViewChild, ViewContainerRef e ComponentFactoryResolver do @angular/core
- ComponentRef e ComponentFactory do @angular/core
- MessageComponent de message.component
Depois de importar as coisas necessárias, o AppComponnet será semelhante à seguinte listagem:
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 acessar o modelo como o ViewChild dentro da classe Component. Template é um contêiner no qual queremos carregar o componente dinamicamente. Portanto, temos que acessar o templo como ViewConatinerRef.
ViewContainerRef representa o contêiner em que uma ou mais exibições podem ser anexadas. Isso pode conter dois tipos de visualizações.
- Host Views
- Embedded Views
As exibições de host são criadas instanciando um componente usando createComponent e as exibições incorporadas são criadas instanciando um modelo incorporado usando createEmbeddedView. Usaremos Host Views para carregar dinamicamente o MessageComponent.
Vamos criar uma variável chamada entry que fará referência ao elemento do modelo. Além disso, injetamos serviços ComponentFactoryResolver na classe de componente, que serão necessários para carregar dinamicamente o componente.
export class AppComponent {
title = 'app';
@ViewChild('messagecontainer', { read: ViewContainerRef }) entry: ViewContainerRef;
constructor(private resolver: ComponentFactoryResolver) { }
}
Lembre-se de que a variável de entrada que é referência ao elemento do modelo possui API para criar componentes, destruir componentes, etc.
Agora, para criar um componente, vamos criar uma função. Dentro da função, precisamos executar as seguintes tarefas,
- Limpe o recipiente
- Criar uma fábrica para MessageComponent
- Criar componente usando a fábrica
- Passar valor para propriedades @Input usando o método de instância de referência de componente
Juntando tudo, a função createComponent será semelhante à lista abaixo:
createComponent(message) {
this.entry.clear();
const factory = this.resolver.resolveComponentFactory(MessageComponent);
const componentRef = this.entry.createComponent(factory);
componentRef.instance.message = message;
}
Podemos chamar a função createComponent no evento de clique do botão. Vamos colocar dois botões no modelo e chamar a função createComponent ao clicar nos botões.
<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>
Na saída, você pode ver que o componente está sendo carregado dinamicamente ao clicar no botão.

Ao clicar no componente de botões, será recarregado com uma mensagem diferente. Você pode destruir um componente usando o método destroy no componentRef.
destroyComponent() {
this.componentRef.destroy();
}
Você pode destruir o componente carregado dinamicamente chamando manualmente a função ou colocá-lo dentro do gancho do ciclo de vida ngOnDestroy() do componente, de modo que, quando o componente host for destruído automaticamente, o componente carregado dinamicamente também será destruído.
Juntando tudo, o AppComponent se parecerá com a lista abaixo:
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();
}
}
Neste ponto, na execução do aplicativo, você receberá um erro porque não definimos o entryComponents no AppModule. Podemos definir isso conforme mostrado na lista abaixo:
import { AppComponent } from './app.component';
import { MessageComponent } from './message.component';
@NgModule({
declarations: [
AppComponent, MessageComponent
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent],
entryComponents: [MessageComponent]
})
export class AppModule { }
Isso é tudo que você precisa fazer para carregar um componente dinamicamente no Angular.
Gostou deste post?
E aí está! Se você gostou deste post, por favor, curta e compartilhe. Além disso, se você ainda não fez check-outInfragistics Ignite UI for Angular, certifique-se de fazê-lo! Eles têm 50+ componentes de Angular baseados em materiais para ajudá-lo a codificar aplicativos da web rápidos com mais rapidez.