Kurs Angular · Moduł 8: Formularze

FormArray - Dynamiczne Pola

1 min czytania ·

FormArray pozwala na dynamiczne dodawanie i usuwanie pól - jak dodawanie nowych technik do arsenału samuraja!

import { FormArray, FormBuilder, FormGroup } from '@angular/forms';

interface SkillForm {
  name: FormControl<string>;
  level: FormControl<number>;
}

@Component({
  template: `
    <form [formGroup]="samuraiForm" (ngSubmit)="onSubmit()">
      <input formControlName="name" placeholder="Imię samuraja">

      <h3>Umiejętności</h3>
      <div formArrayName="skills">
        @for (skill of skills.controls; track $index; let i = $index) {
          <div [formGroupName]="i" class="skill-row">
            <input formControlName="name" placeholder="Nazwa umiejętności">
            <input formControlName="level" type="number" placeholder="Poziom">
            <button type="button" (click)="removeSkill(i)">×</button>
          </div>
        }
      </div>

      <button type="button" (click)="addSkill()">Dodaj umiejętność</button>

      <button type="submit">Zapisz</button>
    </form>
  `
})
export class DynamicFormComponent {
  private fb = inject(FormBuilder);

  samuraiForm = this.fb.group({
    name: ['', Validators.required],
    skills: this.fb.array<FormGroup<SkillForm>>([])
  });

  // Getter dla łatwego dostępu
  get skills(): FormArray<FormGroup<SkillForm>> {
    return this.samuraiForm.get('skills') as FormArray;
  }

  addSkill(): void {
    const skillGroup = this.fb.group({
      name: ['', Validators.required],
      level: [1, [Validators.min(1), Validators.max(10)]]
    });
    this.skills.push(skillGroup);
  }

  removeSkill(index: number): void {
    this.skills.removeAt(index);
  }

  onSubmit(): void {
    if (this.samuraiForm.valid) {
      console.log(this.samuraiForm.value);
      // { name: 'Musashi', skills: [{ name: 'Kendo', level: 5 }, ...] }
    }
  }
}

Inicjalizacja z danymi

loadSamurai(samurai: Samurai): void {
  // Reset i ustawienie prostych pól
  this.samuraiForm.patchValue({
    name: samurai.name
  });

  // Wyczyść i dodaj umiejętności
  this.skills.clear();
  samurai.skills.forEach(skill => {
    this.skills.push(this.fb.group({
      name: [skill.name, Validators.required],
      level: [skill.level]
    }));
  });
}

Hasła z dokumentacji w tej lekcji

Widzisz błąd w tej lekcji?

Sprawdź się

Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.

  1. 1. Do czego służy FormArray?

  2. 2. Której metody używasz, aby dodać nową kontrolkę na koniec FormArray?

To 2 z 3 pytań do tej lekcji. Pozostałe rozwiążesz w grze.

Zadania praktyczne w grze

  • Edytor kodu

    Uzupełnij formularz z dynamiczną listą umiejętności samuraja.

  • Układanie w poziomie

    Ułóż tokeny nagłówka pętli iterującej po kontrolkach FormArray (jedna linia): @for (skill of skills.controls; track $index)

  • Układanie w pionie

    Uporządkuj kroki ponownego wypełnienia FormArray danymi samuraja (kolejność wykonania w metodzie, linia po linii).

  • Klikanie w kolejności

    Zbuduj ciało gettera zwracającego FormArray: return this.form.get('skills') as FormArray. Klikaj elementy po kolei.

Przydatne artykuły