18 gru 2025
4 min

Budowanie dynamicznych formularzy w Angularze z użyciem JSON Schema i Sygnałów

W nowoczesnych aplikacjach formularze są wszędzie — procesy rejestracji, onboarding, konfiguracje produktów, ankiety, panele administracyjne i wiele więcej. Jednak ręczne kodowanie każdego formularza szybko staje się zbyt uciążliwe, zwłaszcza gdy wymagania często się zmieniają. A co, jeśli UI mógłby automatycznie dostosowywać się do konfiguracji bez każdorazowej modyfikacji komponentu Angular?

Tutaj właśnie błyszczą dynamiczne formularze oparte na JSON.

Zamiast ręcznie pisać kontrolki formularzy, definiujesz strukturę w pliku JSON lub pobierasz ją z API. Angular generuje wtedy UI dynamicznie, w oparciu o tę konfigurację. A dzięki wprowadzeniu Angular Signals ten wzorzec staje się jeszcze potężniejszy: bardziej reaktywny, przewidywalny i zdecydowanie czystszy.

W tym wpisie omówimy, jak zaprojektować w pełni dynamiczny system formularzy używając JSON Schema i Angular Signals bez wchodzenia w kod implementacji.

Dlaczego warto budować formularze z użyciem JSON Schema?

Hardkodowane formularze stwarzają wiele problemów:

  • Każde nowe pole wymaga zmian w UI i w kodzie TypeScript.
  • Walidacje trzeba pisać wielokrotnie od zera.
  • Różne role użytkowników lub scenariusze mogą wymagać różnych wersji tego samego formularza.
  • Zespoły biznesowe często zmieniają wymagania szybciej, niż developerzy mogą aktualizować kod.

Z kolei dzięki użyciu JSON Schema:

  • Struktura formularza istnieje poza kodem aplikacji.
  • UI staje się konfiguracyjne, a nie oparte na kodzie.
  • Aktualizacje są natychmiastowe — zmień JSON → odśwież widok.
  • Ten sam komponent może dynamicznie renderować wiele różnych formularzy.

Ten wzorzec jest powszechnie stosowany w platformach workflow, systemach onboardingowych i HR, narzędziach ankietowych, CMS-ach oraz no-code form builderach.

Jak działa architektura (koncepcyjnie)

Dynamiczny system formularzy składa się z pięciu kluczowych elementów.

Przykładowy plik JSON:

{
  "title": "User Registration",
  "fields": [
    {
      "type": "text",
      "label": "First Name*",
      "name": "firstName",
      "validations": { "required": true, "minLength": 3 }
    },
    {
      "type": "text",
      "label": "Last Name*",
      "name": "lastName",
      "validations": { "required": true }
    },
    {
      "type": "email",
      "label": "Email",
      "name": "email",
      "validations": { "required": false }
    },
    {
      "type": "select",
      "label": "Country*",
      "name": "country",
      "options": ["Bangladesh", "Poland", "Turkey"],
      "validations": { "required": true }
    },
    {
      "type": "checkbox",
      "label": "Accept Terms*",
      "name": "terms",
      "validations": { "requiredTrue": true }
    }
  ]
}

1. JSON Schema

To prosty plik JSON lub odpowiedź z API, która opisuje:

  • tytuł formularza
  • listę pól
  • typy pól (text, email, select, checkbox itd.)
  • reguły walidacyjne (required, minLength, requiredTrue)
  • opcje dropdownów

Backend lub CMS może zmieniać to bez dotykania kodu Angulara.

2. Dynamic Form Service

Ten serwis ładuje JSON Schema z assets lub API.

Jego zadania:

  • pobranie metadanych formularza,
  • przygotowanie wartości początkowych,
  • przekazanie schematu do komponentu.

Dzięki temu logika pobierania zostaje wyizolowana, a komponent pozostaje czysty.

3. Signals do zarządzania stanem formularza

Signals zapewniają bardzo reaktywny sposób zarządzania stanem UI. Eliminują ręczne subskrypcje i upraszczają change detection.

Typowy formularz dynamiczny oparty na Signals posiada:

  • fields – listę definicji pól
  • title – nagłówek formularza
  • values – bieżące dane wpisane przez użytkownika
  • touched – śledzenie, które pola użytkownik edytował
  • errors (computed) – automatycznie obliczane błędy walidacji
  • isValid (computed) – określa, czy można wysłać formularz

Za każdym razem, gdy wartość pola się zmieni, Signals propagują zmiany automatycznie i bez subskrypcji w całym UI.

4. Dynamiczne renderowanie w szablonie

Szablon nie zawiera żadnych twardo zakodowanych pól formularza.

Zamiast tego iteruje po liście pól ze schematu i renderuje:

  • Inputy tekstowe lub maili 
  • Selecty dropdownów
  • Checkboxy
  • Komunikaty walidacji

Poprawny element UI pojawia się automatycznie w zależności od typu pola.


Dodajesz nowe pole w JSON-ie? Pojawia się ono natychmiast w UI.


To jest sedno renderowania opartego na konfiguracji.

5. Przepływ wysyłania formularza

Gdy formularz jest poprawny i zostaje wysłany:

  • Zbierany jest stan przechowywany w signals.
  • Jest on przetwarzany, np. poprzez wysłanie do API.

Ponieważ formularz jest oparty na schemacie, logika wysyłania jest jedyną częścią, która pozostaje statyczna.

Dlaczego Angular Signals sprawiają, że jest to lepsze rozwiązanie

Przed Signals dynamiczne formularze zazwyczaj wymagały użycia reactive forms z dużą liczbą kontrolek, subskrypcji i boilerplate’u. Signals znacząco to upraszczają.

Najważniejsze zalety to:

  • Automatyczne przeliczanie wartości pochodnych (błędy, stany walidacji).
  • Brak ręcznego zarządzania subskrypcjami i ich odpinania.
  • Bardziej przewidywalna architektura oparta na stanie.
  • Prostszy model mentalny: „stan wchodzi, UI wychodzi”.

Signals idealnie wpisują się w ideę formularza jako stanu.

Przepływ danych: jak wszystko się łączy

  1. Angular ładuje schemat JSON.
  2. Serwis mapuje go na pola, wartości początkowe oraz stan touched.
  3. Signals przechowują stan formularza w sposób reaktywny.
  4. Szablon renderuje UI na podstawie pól ze schematu.
  5. Gdy użytkownik wchodzi w interakcję, signals aktualizują się natychmiast.
  6. Walidacje obliczane (computed) są ponownie ewaluowane.
  7. Przycisk wysyłania aktywuje się, gdy wszystkie walidacje przejdą pomyślnie.
  8. Wartości końcowe są wysyłane lub logowane.

Daje to czysty, łatwy w utrzymaniu i skalowalny workflow.

Przykłady użycia 

To podejście jest wykorzystywane w takich scenariuszach jak:

  • Form buildery dla platform no-code.
  • Systemy onboardingowe HR, w których pytania różnią się w zależności od roli.
  • Panele administracyjne, gdzie pola często się zmieniają.
  • Wieloetapowe kreatory (wizardy).
  • Dynamiczne landing pages sterowane przez CMS.
  • Interfejsy konfiguracyjne w aplikacjach SaaS.

Zamiast każdorazowo zmieniać kod Angulara, wystarczy dostarczyć nowy plik JSON.

Kiedy powinniśmy stosować to podejście?

Ten wzorzec jest najbardziej wartościowy, gdy:

  • Pola formularza często się zmieniają.
  • Wiele formularzy współdzieli tę samą logikę renderowania.
  • Chcesz umożliwić osobom nietechnicznym aktualizowanie UI poprzez JSON.
  • Zależy Ci na czystej i łatwej w utrzymaniu architekturze Angulara.
  • Budujesz wielokrotnego użytku silnik formularzy.

Jeśli formularze rzadko się zmieniają, ręczne formularze mogą być prostsze. Jednak dla dynamicznych, data-driven UI, połączenie JSON + Signals jest idealnym rozwiązaniem.

Podsumowanie

Dynamiczne formularze oparte na JSON Schema i Angular Signals łączą dwa potężne podejścia:

  • UI sterowane konfiguracją
  • Reaktywne zarządzanie stanem

Razem pozwalają budować elastyczne, łatwe w utrzymaniu i skalowalne systemy formularzy, które natychmiast dostosowują się do potrzeb biznesowych.


To podejście eliminuje powtarzalny kod formularzy, zmniejsza narzut utrzymania UI i umożliwia tworzenie formularzy, które ewoluują bez konieczności ponownego wdrażania aplikacji.

Link do Stackblitz:

https://stackblitz.com/edit/dynamic-form-angularv019?file=src%2Fmain.ts
Podziel się artykułem

Zapisz się na nasz newsletter

Dołącz do community Angular.love i bądź na bieżąco z trendami.