Artikel

Angular v21 – meine Highlights

Ich nutze Angular seit Version 1, als es noch AngularJS hieß. Letzte Woche kam nun Version 21 raus, die wieder mit einigen kleinen und großen Änderungen daherkommt.

Meine persönlichen Highlights sind die neuen Signal-Forms, Verbesserungen der Barrierefreiheit (Angular Aria), der neue Standard-Test-Runner Vitest sowie die Einstell-Möglichkeiten für @defer.

Bild von Enzo Volkmann, dem Autor dieses Artikels 24.11.2025

Entwicklung von Formularen: Signal-Forms

Angular setzt seit gut zwei Jahren auf die sog. Signals. Signals werden verwendet, um den aktuellen Zustand (State) einer Web-Komponenten oder einer ganzen Web-App auf elegante Weise zu speichern und für die Anzeige zu verwenden.

Ein einfaches Beispiel wäre ein fiktiver Taschenrechner, der zwei Zahlen addieren kann. Die beiden Eingabezahlen würden in Angular als Signals angelegt.

Es gibt einige Arten von speziellen Signals, zum Beispiel computed(), also abgeleitete oder berechnete Signals. In unserem Beispiel kann ein Computed Signal verwendet werden, um das Ergebnis des Taschenrechners zu ermitteln.

Durch die Nutzung von Signals ist der Ergebnis-Wert nun immer garantiert richtig und aktuell. Das Ergebnis reagiert automatisch auf Änderungen von einem oder beiden Eingabewerten.

const a = signal(0);
const b = signal(0);

const result = computed(() => a() + b());

Das result() kann nun direkt im HTML-Code genutzt werden, um das Ergebnis anzuzeigen.

<!-- Eingabefelder hier ... -->

Das Ergebnis ist {{result()}}.

Das ist schon ein riesen Vorteil und erleichtert die Entwicklung enorm. Angular Signals haben seither Einzug gehalten in die gesamte Entwicklungsarbeit und sind der neue Standard.

Ein wichtiger Bestandteil der Anwendungsentwicklung, der noch nicht perfekt mit Signals integriert war, waren Formulare, also Eingabefelder für Zahlen, Text, An/Aus, Mehrfachauswahl, usw.

Mit Angular 21 gibt es nun eine native, auf Signals basierende Implementierung, die eine sehr saubere und einfache Entwicklung von Formularfeldern ermöglicht – mit allen Vorteilen von Signals, wie Reaktivität usw. Es folgt das Taschenrechner-Beispiel mit der Nutzung der neuen Signal-Forms.

import { signal, computed } from '@angular/core';
import { form, Field } from '@angular/forms/signals';

@Component({
  imports: [Field],
  template: `
    A: <input [field]="calculatorForm.a">
    B: <input [field]="calculatorForm.b">

    Ergebnis: {{result()}}
  `
})
export class LoginForm {
  calculator = signal({
    a: '',
    b: ''
  });
  
  calculatorForm = form(this.calculator);

  result = computed(() => this.calculator().a + this.calculator().b);
}

Das neue Formular funktioniert nun wie folgt:

  • mit signal() wird das Datenmodell (hier die Zahlen a und b) angelegt

  • mit form() wird daraus ein interaktives und reaktives Formular

  • Im Template werden die input-Elemente mittels field an das entsprechende Formular-Feld gebunden

  • Die Ergebnis-Berechnung bleibt unverändert

Das Ergebnis ist sehr sauberer und einfach zu verstehender Code. Durch Signals ist garantiert, dass alle Eingaben immer synchron sind zum Ergebnis, ohne das für diese Synchronisierung und Reaktivität eigener Code geschrieben werden muss.

Ich freue mich, dieses neue Feature ab jetzt einzusetzen!

Verbesserungen der Barrierefreiheit mit Angular Aria

Mit Angular Aria wurden neue Werkzeuge veröffentlicht, die es uns Entwicklern ermöglichen, barrierefreie Komponenten zu bauen.

Barrierefreiheit ist wichtig, damit alle Menschen das Internet gleichermaßen nutzen können, möglichst unabhängig von ihrem Sehvermögen oder der Fähigkeit, eine Maus zu bedienen.

Um Web-Inhalte barrierefrei zu machen, können wir etwa dafür sorgen, dass auch eine Navigation und Interaktion nur mittels Tastatur möglich ist oder das die Bedeutung von Symbolen und Bildern mit erklärendem Text versehen werden, sodass das Sehen und Erkennen nicht mehr notwendig ist.

Angular Aria bringt nun eine Reihe neuer Werkzeuge, mit denen man Angular-spezifisch die Barrierefreiheit erhöhen kann. Sie bauen auf den allgemeinen Vorgaben und Web-Standards auf und machen es uns Angular-Entwicklern leichter, saubere, zugängliche Anwendungen zu entwickeln.

Neuer Standard-Test-Runner: Vitest

In der Software-Entwicklung schreiben wir Tests, um unseren Code gegenüber den Erwartungen abzusichern und geben uns als Entwicklern die Sicherheit, dass zukünftige Änderungen nicht versehentlich bereits existierende Funktionen beschädigen.

Anhand des Taschenrechner-Beispiels könnten wir etwa einen Test schreiben, der erwartet, dass "1 +1 = 2" ergibt.

import { expect, test } from 'vitest';
import { add } from './calculator';

test('1 + 1 = 2', () => {
  expect(add(1, 1)).toBe(2);
});

Wenn wir nun die Taschenrechner-Implementierung – versehentlich – ändern und das Plus durch ein Minus ersetzen, dann würde unser Test fehlschlagen und wir könnten den Fehler bemerken.

Auf diese Weise kann man alle möglichen kleinen und großen Bestandteile einer Software testen und absichern.

Es gibt verschiedene sog. Test-Tunner, die letztlich die geschriebenen Tests ausführen und die Ergebnisse abgleichen. Der inzwischen populärste ist Vitest und Angular macht diesen nun auch zum Standard. Durch die offizielle Integration und Unterstützung von Angular ist die Nutzung von Vitest nun sehr simpel und ohne Mehraufwand oder Workarounds möglich.

Das freut mich sehr, da ich gerade in letzter Zeit wieder mehr Zeit in Tests investiere und diese Neuerung macht das ganze im Angular-Kontext nochmal etwas angenehmer.

Neue Einstellmöglichkeiten für @defer

Seit einigen Versionen gibt es mit dem @defer-Block die Möglichkeit, gewisse Teile einer Web-Anwendung erst später zu laden und somit die Ladenzeit und Netzwerkauslastung zu optimieren.

Das ist zum Beispiel nützlich, wenn ich in meiner Anwendung eine "große" Komponente wie einen Video-Player erst laden und anzeigen möchte, wenn weit genug heruntergescrollt wurde, um den Player sehen zu können.

Dann kann ich mit @defer angeben, dass der entsprechende Block erst beim Eintritt in den Viewport, also ins Sichtfeld des Browsers, geladen werden soll.

@defer (on viewport) {
  <video-player/>
}

Mit Angular 21 gibt es nun die Möglichkeit, feiner einzustellen, wann der Inhalt eines @defer-Blocks gezeigt werden soll. Dafür lassen sich nun die Optionen des zugrundeliegenden IntersectionObserver anpassen.

<div #trigger>
  Player laden, sobald dieser Abschnitt 100px
  vom Bildschirmrand entfernt ist.
</div>

@defer (on viewport({ trigger, rootMargin: '100px' })) {
  <video-player/>
}
Bitte gib dein Einverständnis

Um deinen Like zu speichern, benötigen wir deine Zustimmung zur Verwendung von Cookies.

Dadurch kann die Seite sich merken, dass dir der Artikel gefällt.

Es werden keine personenbezogenen Daten übertragen oder gespeichert. Deine Einwilligung wird für ein Jahr gespeichert.