🚀 Capítulo 11: Formulários Reativos

🎯 Objetivo da Aula

Ao final desta aula, você será capaz de criar formulários complexos e robustos usando a abordagem Reactive Forms (Formulários Reativos), onde toda a lógica e validação ficam centralizadas no arquivo TypeScript, permitindo maior controle e testes.


🏢 O Cenário Prático (Seu Desafio)

Para missões de alto risco, precisamos de um formulário de segurança máxima para Autorização de Lançamento de Caças. Este formulário requer validações avançadas que a abordagem anterior não consegue fazer com facilidade. Seu desafio é criá-lo usando Formulários Reativos!


🧠 Fundamentos: A Teoria Traduzida

Ao contrário dos Formulários Orientados a Template, os Formulários Reativos são definidos no arquivo TypeScript. Eles são mais poderosos, escaláveis e ideais para formulários complexos.

Classes Fundamentais:

  • FormControl: Representa um único campo de entrada (input). Ele guarda o valor e o estado (se está válido, se foi tocado, etc.).
  • FormGroup: É um grupo de FormControls. Ele representa o formulário inteiro ou uma parte dele.
  • Validators: Classe com regras prontas para validação (obrigatório, tamanho mínimo, email, etc.).

Nota: Para usar, precisamos importar o ReactiveFormsModule no componente/módulo.


📖 Exemplo Guiado: Autorização de Lançamento

Vamos criar o formulário reativo.

🛠️ Passo a Passo (TypeScript)

Abra src/app/painel-controle/painel-controle.component.ts:

  1. Importe as classes do @angular/forms:
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';
 
@Component({ /* ... */ })
export class PainelControleComponent implements OnInit {
  formularioSeguro!: FormGroup;
 
  ngOnInit(): void {
    // Definindo a estrutura do formulário no código
    this.formularioSeguro = new FormGroup({
      'codigoAcesso': new FormControl(null, [Validators.required, Validators.minLength(5)]),
      'nivelAutorizacao': new FormControl('1', Validators.required)
    });
  }
 
  enviarAutorizacao() {
    if (this.formularioSeguro.valid) {
      console.log('Dados enviados:', this.formularioSeguro.value);
      alert('Lançamento Autorizado!');
    }
  }
}

🛠️ Passo a Passo (HTML)

Abra src/app/painel-controle/painel-controle.component.html:

<div class="painel">
  <h3>🔒 Autorização de Lançamento</h3>
  
  <!-- Ligamos a tag form ao nosso FormGroup do TS -->
  <form [formGroup]="formularioSeguro" (ngSubmit)="enviarAutorizacao()">
    
    <div>
      <label>Código de Acesso:</label>
      <!-- Ligamos o input ao FormControl específico -->
      <input type="text" formControlName="codigoAcesso">
      <span *ngIf="formularioSeguro.get('codigoAcesso')?.invalid && formularioSeguro.get('codigoAcesso')?.touched" style="color: red;">
        O código deve ter pelo menos 5 caracteres!
      </span>
    </div>
 
    <div>
      <label>Nível de Autorização:</label>
      <select formControlName="nivelAutorizacao">
        <option value="1">Nível 1 (Recruta)</option>
        <option value="2">Nível 2 (Cavaleiro)</option>
        <option value="3">Nível 3 (Mestre)</option>
      </select>
    </div>
 
    <button type="submit" [disabled]="formularioSeguro.invalid">Autorizar</button>
  </form>
</div>

🕹️ Como Executar e Testar no VS Code

  1. Salve tudo e veja o navegador.
  2. Digite apenas 3 letras no código de acesso e clique fora. O erro aparecerá!
  3. O botão só habilitará quando houver 5 ou mais caracteres no primeiro campo.

🛠️ Prática Obrigatória 1

Adicione um validador de tamanho máximo (Validators.maxLength(10)) no campo codigoAcesso.


🛠️ Prática Obrigatória 2

Crie um novo campo no formulário chamado comentarios que não seja obrigatório. Exiba na tela a quantidade de caracteres digitados nesse campo em tempo real (Dica: use formularioSeguro.get('comentarios')?.value?.length).


🔑 Gabarito de Código/Fórmulas

Prática 1:

No .ts:

'codigoAcesso': new FormControl(null, [
  Validators.required, 
  Validators.minLength(5),
  Validators.maxLength(10)
])

Prática 2:

No .ts:

this.formularioSeguro = new FormGroup({
  // ... outros campos
  'comentarios': new FormControl(null)
});

No .html:

<div>
  <label>Comentários:</label>
  <textarea formControlName="comentarios"></textarea>
  <p>Caracteres: {{ formularioSeguro.get('comentarios')?.value?.length || 0 }}</p>
</div>

Capitulo Anterior | Proximo Capitulo