🚀 Capítulo 07: Comunicação entre Componentes
🎯 Objetivo da Aula
Ao final desta aula, você será capaz de fazer dois componentes conversarem entre si, passando dados de um componente pai para um componente filho (@Input) e enviando mensagens (eventos) do filho de volta para o pai (@Output).
🏢 O Cenário Prático (Seu Desafio)
A sua nave principal (Pai) possui um mini-caça de reconhecimento (Filho) acoplado. Você precisa enviar o nível de energia da nave principal para o painel do mini-caça e, quando o piloto do mini-caça apertar o botão de decolar, a nave principal precisa receber esse sinal para abrir as portas do hangar!
🧠 Fundamentos: A Teoria Traduzida
Componentes no Angular são isolados por padrão. Para eles conversarem, usamos decoradores especiais:
1. @Input() (Entrada de Dados)
Serve para o componente Pai passar uma informação para dentro do componente Filho. É como passar combustível da nave mãe para o caça.
- No Filho (.ts):
@Input() energia: number = 0; - No Pai (.html):
<app-mini-caca [energia]="energiaNaveMae"></app-mini-caca>
2. @Output() (Saída de Dados)
Serve para o componente Filho avisar o Pai que algo aconteceu (um evento). Usamos junto com o EventEmitter. É como o caça enviando um rádio para a nave mãe.
- No Filho (.ts):
@Output() decolou = new EventEmitter<void>(); - No Filho (.html):
<button (click)="decolou.emit()">Decolar</button> - No Pai (.html):
<app-mini-caca (decolou)="abrirHangar()"></app-mini-caca>
📖 Exemplo Guiado: Nave Mãe e Mini-Caça
Vamos criar o componente do mini-caça.
🛠️ Passo a Passo (Filho: Mini-Caça)
- Gere o componente:
ng g c mini-caca - No arquivo
mini-caca.component.ts, importe oInput,OutputeEventEmitter:
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-mini-caca',
templateUrl: './mini-caca.component.html',
styleUrls: ['./mini-caca.component.css']
})
export class MiniCacaComponent {
@Input() combustivelFilho: number = 0;
@Output() solicitarDecolagem = new EventEmitter<void>();
emitirSinal() {
this.solicitarDecolagem.emit();
}
}- No arquivo
mini-caca.component.html:
<div style="border: 1px solid yellow; padding: 10px;">
<h3>🛸 Mini-Caça de Reconhecimento</h3>
<p>Combustível recebido da Nave Mãe: {{ combustivelFilho }}%</p>
<button (click)="emitirSinal()">Solicitar Decolagem</button>
</div>🛠️ Passo a Passo (Pai: Painel de Controle)
Abra src/app/painel-controle/painel-controle.component.html e use o componente filho:
<!-- Passando o valor da variável nivelEnergia para o filho -->
<!-- Escutando o evento solicitarDecolagem e chamando a função abrirPortas -->
<app-mini-caca
[combustivelFilho]="nivelEnergia"
(solicitarDecolagem)="abrirPortas()">
</app-mini-caca>(Lembre-se de criar a função abrirPortas() { alert('Portas do Hangar Abertas!'); } no seu painel-controle.component.ts).
🕹️ Como Executar e Testar no VS Code
- Salve tudo e execute
ng serve. - Veja o mini-caça exibindo a mesma energia do painel principal.
- Clique no botão de decolar no mini-caça e veja o alerta disparado pelo componente pai!
🛠️ Prática Obrigatória 1
Passe o nome do piloto (que está no componente pai) para o componente do mini-caça usando @Input e exiba no HTML do mini-caça: “Piloto do Caça: [Nome]“.
🛠️ Prática Obrigatória 2
No mini-caça, crie um botão “Ligar Escudo do Caça” que emite um evento chamado escudoLigado passando um valor booleano (true). O componente pai deve receber esse evento e exibir uma mensagem “Caça com escudos ativos!“.
🔑 Gabarito de Código/Fórmulas
Prática 1:
No Filho (mini-caca.ts):
@Input() nomePilotoFilho: string = '';No Filho (mini-caca.html):
<p>Piloto do Caça: {{ nomePilotoFilho }}</p>No Pai (painel.html):
<app-mini-caca [nomePilotoFilho]="nomePiloto" ...></app-mini-caca>Prática 2:
No Filho (mini-caca.ts):
@Output() escudoLigado = new EventEmitter<boolean>();No Filho (mini-caca.html):
<button (click)="escudoLigado.emit(true)">Ligar Escudo do Caça</button>No Pai (painel.html):
<app-mini-caca (escudoLigado)="mensagemEscudo($event)" ...></app-mini-caca>(Nota: O $event captura o valor enviado pelo emit, no caso true).