Application Framework

Angular

Angular ist das "Batteries-included"-Framework: TypeScript-first, integrierte Dependency Injection und eine strukturierte Architektur, die von kleinen Apps bis hin zu großen Enterprise-Codebases skaliert.

intermediate16 min readUpdated 15. Sept. 2026
counter.component.ts
ts
// counter.component.ts
import { Component, signal } from "@angular/core";

@Component({
  selector: "app-counter",
  standalone: true,
  template: `
    <button (click)="increment()">
      Clicked {{ count() }} times
    </button>
  `,
})
export class CounterComponent {
  count = signal(0);

  increment() {
    this.count.update((c) => c + 1);
  }
}
Gewartet von
Google
Sprache
TypeScript first
Aktuelle Major-Version
Angular 17+
Reaktivität
Signals und RxJS
DI
Im Framework integriert
Umfang
Vollständige Applikationsplattform

Warum es wichtig ist

Warum Unternehmen Angular wählen

Batteries included

Routing, Forms, HTTP, Testing und Tooling werden gemeinsam ausgeliefert, sodass Teams ihren Stack nicht aus einem Dutzend unzusammenhängender Pakete zusammenstellen müssen.

Strukturierte Architektur

Konventionen und Dependency Injection halten große Codebases konsistent, was besonders wichtig ist, wenn viele Entwickler an einem Repository arbeiten.

Für Skalierung gebaut

Starke Typisierung, eine leistungsstarke CLI und ein Testing-Setup vom ersten Tag an machen Angular zu einer gängigen Wahl für langlebige Enterprise-Apps.

Das Gesamtbild

Die drei Grundideen hinter Angular

Ein Komponenten-Baum, Dependency Injection und eine reaktive Ebene. Angular liefert alle drei als ein kohärentes, strukturiertes System aus.

Components

UI

Klassen, die mit @Component dekoriert sind und ein Template mit Logik und Styles verbinden.

Dependency injection

Wiring

Ein First-Class-Container, der Services in der gesamten Anwendung bereitstellt und injiziert.

Reactivity

Change

Signals für den lokalen State und RxJS Observables für Streams, welche die Change Detection steuern.

Angular auf einen Blick

Der Kern von Angular

Components

Eine TypeScript-Klasse, ein HTML-Template und Styles, die durch einen Decorator miteinander verknüpft werden.

Templates & binding

Interpolation, Property Binding und Event Binding verbinden die Klasse mit der View.

Signals

Feingranulare reaktive Werte, die die View aktualisieren, ohne einen vollständigen Check durchzuführen.

RxJS

Observables und Operatoren zur Handhabung asynchroner Event-Streams.

Services & DI

Teile Logik und Daten über injizierbare Services, anstatt globale Variablen zu importieren.

Router

Konfiguriere Routen, Guards und lazy-loaded Feature-Bereiche deklarativ.

Eine kurze Geschichte

Von AngularJS zu einer modernen Plattform

  1. 2010

    AngularJS

    Das ursprüngliche Framework popularisiert Two-Way Binding und Single-Page Applications.

    10
  2. 2016

    Angular 2 Rewrite

    Ein kompletter Neubau basierend auf Komponenten, TypeScript und einem neuen Dependency Injection System.

    16
  3. 2020

    Ivy und Strict Mode

    Ein neuer Compiler verbessert die Bundle-Größe und ermöglicht eine striktere Typprüfung.

    20
  4. 2023

    Signals und Standalone

    Signals werden eingeführt und Standalone Components werden zum empfohlenen Standard.

    23
  5. Heute

    Eine moderne Plattform

    Deferred Loading, zoneless Change Detection und eine vereinheitlichte CLI halten Angular wettbewerbsfähig.

    Heute

Der vollständige Leitfaden

Angular: Alles was Sie wissen müssen

Was ist Angular?

Angular ist ein vollständiges Application Framework, das von Google gepflegt wird. Während React eine Library ist, um die man sich selbst einen Stack zusammenstellt, liefert Angular den gesamten Stack mit: Komponenten, Routing, Formulare, HTTP, Dependency Injection, Testing und eine leistungsstarke CLI – alles darauf ausgelegt, nahtlos zusammenzuarbeiten. Es ist TypeScript-first und opinionated, was genau der Grund ist, warum große Teams darauf setzen.

Diese Vollständigkeit ist der zentrale Trade-off. Man nimmt eine steilere Lernkurve und mehr Framework-Konventionen in Kauf, erhält dafür aber Konsistenz, ein starkes Tooling und muss weniger Architektur-Entscheidungen von Grund auf selbst treffen. Für einen kleinen Prototyp kann sich das schwerfällig anfühlen; für eine fünf Jahre alte Enterprise-Codebase ist es oft eine Erleichterung.

Komponenten und Templates

Eine Komponente ist eine TypeScript-Klasse, die mit @Component dekoriert ist und mit einem HTML-Template sowie optionalen Styles gekoppelt wird.

// user-card.component.ts
import { Component, Input } from "@angular/core";

@Component({
  selector: "app-user-card",
  standalone: true,
  template: `
    <article class="card">
      <h3>{{ user.name }}</h3>
      <p>{{ user.email }}</p>
    </article>
  `,
})
export class UserCardComponent {
  @Input({ required: true }) user!: { name: string; email: string };
}

Das Template verwendet {{ }} für die Interpolation und Directives für die Logik. Modernes Angular nutzt integrierte Control-Flow-Blöcke anstelle der älteren strukturellen Directives.

<!-- list.html -->
@if (users.length > 0) {
  <ul>
    @for (user of users; track user.id) {
      <li>{{ user.name }}</li>
    }
  </ul>
} @else {
  <p>No users yet.</p>
}

Der track-Ausdruck in @for übernimmt die gleiche Rolle wie ein Key in React oder Vue: Er teilt Angular mit, wie Elemente zwischen Updates zugeordnet werden sollen.

Data Binding

Angular-Templates unterstützen vier Arten von Binding.

  • Interpolation {{ value }} rendert einen Wert als Text.
  • Property Binding [src]="url" setzt eine Element-Property über einen Ausdruck.
  • Event Binding (click)="save()" ruft eine Methode auf, wenn ein Event ausgelöst wird.
  • Two-way Binding [(ngModel)]="name" kombiniert beides für Formular-Inputs.
<!-- bindings.html -->
<img [src]="user.avatar" [alt]="user.name" />
<button (click)="save()">Save</button>
<input [(ngModel)]="query" />

Two-way Binding ist praktisch für einfache Formulare, aber für alles, was eine Validierung benötigt, sind Reactive Forms in der Regel die bessere Wahl.

Signals

Signals sind das moderne Reaktivitäts-Primitiv von Angular. Ein Signal hält einen Wert und benachrichtigt interessierte Konsumenten, wenn sich dieser ändert. Dadurch kann das Framework gezielt nur die Teile der View aktualisieren, die von diesem Signal abhängen.

// cart.component.ts
import { Component, signal, computed } from "@angular/core";

@Component({
  selector: "app-cart",
  standalone: true,
  template: `<p>Total: {{ total() }}</p>`,
})
export class CartComponent {
  items = signal([{ price: 10 }, { price: 20 }]);

  total = computed(() =>
    this.items().reduce((sum, i) => sum + i.price, 0),
  );

  add(price: number) {
    this.items.update((items) => [...items, { price }]);
  }
}

computed leitet einen Wert aus anderen Signals ab und cached diesen, bis sich eine Abhängigkeit ändert. effect führt einen Side Effect aus, wenn sich die gelesenen Signals ändern. Zusammen decken sie den Großteil der Anforderungen von Komponenten ab.

RxJS und Observables

Angular verfügt über eine tiefe RxJS-Integration. Ein Observable repräsentiert einen Stream von Werten über einen Zeitraum hinweg, und Operatoren ermöglichen es, diese Streams zu transformieren und zu kombinieren.

// search.component.ts
import { Component } from "@angular/core";
import { toSignal } from "@angular/core/rxjs-interop";
import { debounceTime, distinctUntilChanged, switchMap } from "rxjs";

@Component({ /* ... */ })
export class SearchComponent {
  private query$ = new Subject<string>();

  results = toSignal(
    this.query$.pipe(
      debounceTime(300),
      distinctUntilChanged(),
      switchMap((q) => this.api.search(q)),
    ),
    { initialValue: [] },
  );
}

Hier spielt RxJS seine Stärken aus: Debouncing, das Abbrechen veralteter Requests und das Kombinieren von Streams lassen sich mit einfachen Promises nur schwer ausdrücken. Für einfachen synchronen State sind Signals einfacher. Modernes Angular erlaubt es, beides zu mischen und mithilfe von toSignal und toObservable zu konvertieren.

Services und Dependency Injection

Gemeinsame Logik und Daten gehören in Services, nicht in Komponenten. Dependency Injection stellt diese dort bereit, wo sie benötigt werden.

// users.service.ts
import { Injectable, inject } from "@angular/core";
import { HttpClient } from "@angular/common/http";

@Injectable({ providedIn: "root" })
export class UsersService {
  private http = inject(HttpClient);

  getAll() {
    return this.http.get<User[]>("/api/users");
  }
}
// users.component.ts
export class UsersComponent {
  private users = inject(UsersService);
  list = toSignal(this.users.getAll(), { initialValue: [] });
}

providedIn: "root" registriert ein Singleton für die gesamte App. DI macht es einfach, Services in Tests auszutauschen, und sorgt dafür, dass Komponenten auf die Präsentation fokussiert bleiben.

Routing

Der Angular Router bildet URLs auf Komponenten ab und unterstützt verschachtelte Routen, Guards, Resolver und Lazy Loading.

// app.routes.ts
import { Routes } from "@angular/router";

export const routes: Routes = [
  { path: "", component: HomeComponent },
  { path: "users/:id", component: UserProfileComponent },
  {
    path: "admin",
    loadChildren: () => import("./admin/admin.routes").then((m) => m.ADMIN_ROUTES),
  },
];

Durch das Lazy Loading von Funktionsbereichen bleibt das initiale Bundle klein, und Guards ermöglichen es, die Navigation zu blockieren, bis eine bestimmte Bedingung, wie etwa die Authentifizierung, erfüllt ist.

Formulare und HTTP

Angular bietet zwei Ansätze für Formulare. Reactive forms definieren das Modell und die Validatoren in der Klasse, was gut skalierbar und testbar ist. Template-driven forms nutzen Direktiven wie ngModel und sind für einfache Anwendungsfälle schneller umzusetzen.

// signup.component.ts
form = new FormGroup({
  email: new FormControl("", [Validators.required, Validators.email]),
  password: new FormControl("", [Validators.required, Validators.minLength(8)]),
});

submit() {
  if (this.form.invalid) return;
  this.http.post("/api/signup", this.form.getRawValue()).subscribe();
}

HttpClient gibt Observables zurück, sodass Anfragen mithilfe von RxJS-Operatoren für Retries, Stornierungen und die Fehlerbehandlung kombiniert werden können.

Best Practices

  • Bevorzuge für neuen Code standalone components und signals.
  • Halte components auf die Präsentation fokussiert und lagere die Logik in services aus.
  • Nutze reactive forms für alles, was Validierungen oder dynamische Felder benötigt.
  • Nutze Lazy-Loading für Feature-Bereiche, um das initiale Bundle klein zu halten.
  • Verwende OnPush change detection oder signals, um unnötige Checks zu begrenzen.
  • Tracke Items in @for mit einem stabilen, eindeutigen Wert.
  • Melde dich von langlebigen observables ab oder nutze die async pipe und toSignal.

Häufige Fehler

  • Business-Logik in Komponenten statt in Services zu platzieren.
  • Manuelles Abonnieren (Subscribe) ohne anschließendes Unsubscribe, was zu Memory Leaks führt.
  • Auf RxJS zurückzugreifen, wenn ein Signal einfacher wäre.
  • Den Wert eines Signals direkt zu mutieren, anstatt set oder update zu verwenden.
  • Ein einziges riesiges NgModule zu bauen, anstatt auf lazy-loaded Feature-Routes zu setzen.
  • Angular wie React zu behandeln und gegen die Struktur des Frameworks zu arbeiten.

Wie geht es weiter?

Angular belohnt Geduld mit einer Struktur, die über Jahre hinweg Bestand hat. Vertiefe deine TypeScript-Kenntnisse, verstehe die Unterschiede zu React und Vue und lerne das Node.js-Tooling kennen, das hinter der CLI steckt. Baue anschließend ein Feature mit Routing, einem Service und einem reaktiven Formular, um zu sehen, wie die einzelnen Teile ineinandergreifen.

Lokaler State

Signals sind der moderne Standard für synchronen Komponenten-State. Nutze RxJS, wenn du tatsächlich einen Stream hast.

Bevorzugt
const count = signal(0);
count.update((c) => c + 1);
// read it in the template
// {{ count() }}
Vermeiden
count$ = new BehaviorSubject(0);
count$.next(
  this.count$.value + 1,
);
// needs an async pipe

Formulare erstellen

Reactive Forms halten das Modell in der Klasse, was bei Validierungen und dynamischen Feldern besser skaliert.

Reactive
form = new FormGroup({
  email: new FormControl("", [
    Validators.required,
    Validators.email,
  ]),
});
Template-driven
<form #f="ngForm">
  <input
    name="email"
    ngModel
    required
    email
  />
</form>

Häufig gestellte Fragen

Häufig gestellte Fragen

Keep learning

Related topics from the roadmap.

$ Lernen Sie jetzt

Bereit, Angular zu lernen?

Unser interaktives Tutorial führt Sie Schritt für Schritt durch Angular — mit Quizzen und echtem Code, den Sie im Browser ausführen können.