🚀 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)

  1. Gere o componente: ng g c mini-caca
  2. No arquivo mini-caca.component.ts, importe o Input, Output e EventEmitter:
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();
  }
}
  1. 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

  1. Salve tudo e execute ng serve.
  2. Veja o mini-caça exibindo a mesma energia do painel principal.
  3. 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).


Capitulo Anterior | Proximo Capitulo