🚀 Capítulo 18: Gerenciamento de Estado (Signals)
🎯 Objetivo da Aula
Ao final desta aula, você entenderá o que são os Signals (Sinais), o novo e poderoso recurso do Angular para gerenciamento de estado, e saberá como usá-los para atualizar a tela de forma muito mais rápida e performática.
🏢 O Cenário Prático (Seu Desafio)
O painel da sua nave precisa atualizar o nível de oxigênio e calcular o tempo de sobrevivência restante a cada segundo. Usar o sistema antigo pode deixar o painel lento. Seu desafio é usar os Signals para criar um painel ultra-rápido e reativo!
🧠 Fundamentos: A Teoria Traduzida
Antes dos Signals, o Angular precisava checar a aplicação inteira para saber o que mudou na tela (Zone.js). Com os Signals, o Angular sabe exatamente qual pedacinho da tela mudou e atualiza só aquilo!
Existem 3 conceitos principais:
1. signal (O Sinalizador)
É uma variável que avisa o Angular quando seu valor muda.
- Criação:
oxigenio = signal(100); - Leitura (no HTML ou TS):
{{ oxigenio() }}(precisa dos parênteses!). - Mudança:
oxigenio.set(90);ouoxigenio.update(v => v - 10);
2. computed (O Calculado)
É um valor que depende de outro signal e se atualiza sozinho.
- Exemplo:
tempoRestante = computed(() => this.oxigenio() * 2);
3. effect (O Efeito)
Uma função que roda sozinha sempre que o signal dentro dela mudar (ótimo para salvar dados ou dar alertas).
📖 Exemplo Guiado: Contador de Oxigênio
Vamos usar Signals no nosso componente.
🛠️ Passo a Passo (TypeScript)
No seu painel-controle.component.ts:
- Importe o
signale ocomputed:
import { Component, signal, computed } from '@angular/core';
@Component({ /* ... */ })
export class PainelControleComponent {
// Criando um Signal
oxigenio = signal(100);
// Criando um valor calculado (depende do oxigenio)
statusAlerta = computed(() => {
return this.oxigenio() < 20 ? '🚨 CRÍTICO' : 'Normal';
});
gastarOxigenio() {
// Atualiza o valor do signal
this.oxigenio.update(valorAtual => valorAtual - 5);
}
}🛠️ Passo a Passo (HTML)
No HTML:
<div class="painel">
<h3>Status de Sobrevivência</h3>
<!-- Lembre-se de usar os parênteses () para ler o signal! -->
<p>Nível de Oxigênio: **{{ oxigenio() }}%**</p>
<p>Status: **{{ statusAlerta() }}**</p>
<button (click)="gastarOxigenio()">Simular Gasto</button>
</div>🕹️ Como Executar e Testar no VS Code
- Salve e clique no botão no navegador.
- Veja o número diminuir. Quando chegar abaixo de 20, o status mudará para ”🚨 CRÍTICO” na hora!
🛠️ Prática Obrigatória 1
Crie um signal chamado cargaBateria iniciando em 100. Crie um botão que diminua a carga em 10 a cada clique.
🛠️ Prática Obrigatória 2
Crie um valor computed chamado bateriaBaixa que retorne true se a carga da bateria for menor que 30, e false caso contrário. Use o *ngIf para mostrar uma mensagem de “Conecte o carregador” baseada nesse computed.
🔑 Gabarito de Código/Fórmulas
Prática 1:
No .ts:
cargaBateria = signal(100);
gastarBateria() {
this.cargaBateria.update(v => v - 10);
}Prática 2:
No .ts:
bateriaBaixa = computed(() => this.cargaBateria() < 30);No .html:
<p *ngIf="bateriaBaixa()" style="color: orange;">⚠️ Conecte o carregador!</p>