🚀 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); ou oxigenio.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:

  1. Importe o signal e o computed:
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

  1. Salve e clique no botão no navegador.
  2. 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>

Capitulo Anterior | Proximo Capitulo