Spec Frontend Com Angular • Trilha Progressiva em 4 Níveis


🎯 Nível 1: Fundamentos

Problema 13.1 — Formulário Reativo com FormBuilder e FormControl

Contexto: Formulário Reativo com FormBuilder e FormControl no contexto de Reactive Forms, FormBuilder e Validações Customizadas.

Requisitos de Execução:

  1. Criar formulário de login com FormBuilder.group({ email: ['', [Validators.required, Validators.email]] }).

Resultado Esperado

Formulário reativo com validações síncronas integradas.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_13_1_SeuNome
  2. Envie na tarefa: Atividade Cap 13 - Reactive Forms, FormBuilder e Validações Customizadas
🔑 Gabarito de Código & Solução Comentada
// login-form.component.ts
import { Component, inject } from '@angular/core';
import { ReactiveFormsModule, FormBuilder, Validators } from '@angular/forms';

@Component({
  selector: 'app-login-form',
  standalone: true,
  imports: [ReactiveFormsModule],
  template: `
    <form [formGroup]="form" (ngSubmit)="onSubmit()">
      <input formControlName="email" placeholder="E-mail" />
      <button type="submit" [disabled]="form.invalid">Entrar</button>
    </form>
  `
})
export class LoginFormComponent {
  private fb = inject(FormBuilder);
  form = this.fb.group({
    email: ['', [Validators.required, Validators.email]],
    senha: ['', [Validators.required, Validators.minLength(6)]]
  });

  onSubmit() { console.log('Dados:', this.form.value); }
}

🔍 Nível 2: Prática

Problema 13.2 — Validador Customizado Síncrono (ValidatorFn)

Contexto: Validador Customizado Síncrono (ValidatorFn) no contexto de Reactive Forms, FormBuilder e Validações Customizadas.

Requisitos de Execução:

  1. Criar validador validarDominioEmpresa('empresa.com') que rejeite emails de domínios públicos.

Resultado Esperado

Validador de domínio corporativo aplicado ao campo de e-mail.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_13_2_SeuNome
  2. Envie na tarefa: Atividade Cap 13 - Reactive Forms, FormBuilder e Validações Customizadas
🔑 Gabarito de Código & Solução Comentada
// validators.ts
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';

export function validarDominioEmpresa(dominioEsperado: string): ValidatorFn {
  return (control: AbstractControl): ValidationErrors | null => {
    const email = control.value as string;
    if (!email) return null;
    return email.endsWith(`@${dominioEsperado}`) ? null : { dominioInvalido: true };
  };
}

⚡ Nível 3: Integração

Problema 13.3 — Campos Dinâmicos com FormArray

Contexto: Campos Dinâmicos com FormArray no contexto de Reactive Forms, FormBuilder e Validações Customizadas.

Requisitos de Execução:

  1. Implementar formulário com lista dinâmica de telefones permitindo adicionar e remover campos com FormArray.

Resultado Esperado

Campos de formulário adicionados e removidos dinamicamente no FormArray.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_13_3_SeuNome
  2. Envie na tarefa: Atividade Cap 13 - Reactive Forms, FormBuilder e Validações Customizadas
🔑 Gabarito de Código & Solução Comentada
// dynamic-form.component.ts
import { Component, inject } from '@angular/core';
import { ReactiveFormsModule, FormBuilder, FormArray } from '@angular/forms';

@Component({
  selector: 'app-dynamic-form',
  standalone: true,
  imports: [ReactiveFormsModule],
  template: `
    <form [formGroup]="form">
      <div formArrayName="telefones">
        @for (ctrl of telefones.controls; track $index) {
          <input [formControlName]="$index" />
        }
      </div>
      <button type="button" (click)="adicionarTelefone()">+ Telefone</button>
    </form>
  `
})
export class DynamicFormComponent {
  private fb = inject(FormBuilder);
  form = this.fb.group({ telefones: this.fb.array([this.fb.control('')]) });
  get telefones() { return this.form.get('telefones') as FormArray; }
  adicionarTelefone() { this.telefones.push(this.fb.control('')); }
}

🏆 Nível 4: Desafio Corporativo

Problema 13.4 — Validação Assíncrona com AsyncValidatorFn e Debounce

Contexto: Validação Assíncrona com AsyncValidatorFn e Debounce no contexto de Reactive Forms, FormBuilder e Validações Customizadas.

Requisitos de Execução:

  1. Criar validador assíncrono consultando API para verificar se o nome de usuário já está cadastrado.

Resultado Esperado

Validação assíncrona executada com debounce evitando sobrecarga no servidor.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_13_4_SeuNome
  2. Envie na tarefa: Atividade Cap 13 - Reactive Forms, FormBuilder e Validações Customizadas
🔑 Gabarito de Código & Solução Comentada
// async-validator.ts
import { AbstractControl, AsyncValidatorFn } from '@angular/forms';
import { timer, of } from 'rxjs';
import { switchMap, map } from 'rxjs/operators';

export function checarUsuarioDisponivel(): AsyncValidatorFn {
  return (control: AbstractControl) => {
    return timer(400).pipe(
      switchMap(() => control.value === 'admin' ? of({ usuarioJaExiste: true }) : of(null))
    );
  };
}