Angular Programmierung: Der Komplett-Guide
1. Die Projekt-Struktur (Statischer Aufbau)
Bevor du die erste Zeile Code schreibst, musst du wissen, wo was hingehört. Angular nutzt eine strikte Ordnerhierarchie, damit Projekte auch bei hunderten Dateien übersichtlich bleiben.
src/app/
├── models/ # Schritt 1: Was wird gespeichert? (Interfaces)
├── services/ # Schritt 2: Woher kommen die Daten? (Logik)
├── components/ # Schritt 3 & 4: Wie sieht es aus? (UI)
│ └── user-list/ # Jede Komponente hat ihren eigenen Ordner
│ ├── user-list.component.ts # Die Logik
│ └── user-list.component.html # Die Anzeige
└── app.config.ts # Die Schaltzentrale (Konfiguration)
- app.config.ts: Hier registrierst du globale Funktionen, wie zum Beispiel den
provideHttpClient(), falls du später Daten aus dem Internet laden willst. - index.html: Die einzige echte HTML-Seite deiner App. Sie dient nur als Hülle für deine Angular-Komponenten.
2. Der Programmier-Workflow (Schritt für Schritt)
In Angular arbeiten wir uns von der Datenstruktur (innen) zur Anzeige (außen) vor.
Schritt 1: Das Model (name.model.ts)
Eine reine TypeScript-Datei für Interfaces. Hier wird kein Code ausgeführt, sondern nur definiert, wie Daten aussehen.
// datei: student.model.ts
export interface Student {
id: number;
name: string;
}
Schritt 2: Der Service (name.service.ts)
Die Logik-Zentrale. Hier werden Daten verwaltet, gefiltert oder vom Server geladen.
// datei: student.service.ts
import { Injectable } from '@angular/core';
import { Student } from '../models/student.model';
@Injectable({ providedIn: 'root' })
export class StudentService {
getStudents(): Student[] {
return [{ id: 1, name: 'Tim' }];
}
}
Schritt 3: Die Komponenten-Klasse (name.component.ts)
Die Verbindungsdatei. Sie importiert den Service und bereitet die Daten für das HTML vor.
// datei: student-list.component.ts
import { Component, OnInit } from '@angular/core';
import { StudentService } from '../../services/student.service';
import { Student } from '../../models/student.model';
@Component({
selector: 'app-student-list',
templateUrl: './student-list.component.html'
})
export class StudentListComponent implements OnInit {
liste: Student[] = [];
constructor(private api: StudentService) {} // Dependency Injection
ngOnInit() {
this.liste = this.api.getStudents();
}
}
Schritt 4: Das Template (name.component.html)
Die Anzeige-Datei. Hier nutzt man Angular-Befehle, um die Daten aus der .ts-Datei sichtbar zu machen.
<!-- datei: student-list.component.html -->
<ul>
@for (s of liste; track s.id) {
<li> {{ s.name }} </li>
}
</ul>
3. Architektur: Warum die strikte Trennung?
| Schicht | Verantwortung | Warum getrennt? |
|---|---|---|
| Model | Datenstruktur | Sicherheit: Verhindert Tippfehler. TypeScript meckert bei Fehlern sofort. |
| Service | Datenlogik | Wiederverwendbarkeit: Zehn Komponenten können denselben Service nutzen. |
| Komponente | Zustand & Event-Handling | Übersicht: Hier steht nur, *was* passiert, nicht *wie* Daten gespeichert werden. |
| Template | Präsentation (UI) | Design-Fokus: Reiner HTML-Code mit Bindings für ungestörtes UI-Design. |
Merksatz: Eine Komponente sollte niemals direkt wissen, wie Daten gespeichert werden. Sie fragt einfach den Service. Das macht deine App flexibel!
4. Wichtige Befehle & Syntax
ng serve- Startet den lokalen Entwicklungsserver.ng g c component-name- Erzeugt eine neue Komponente.ng g s service-name- Erzeugt einen neuen Service.
Template-Binding
- Interpolation:
{{ variable }}(Einfache Textausgabe) - Property-Binding:
[property]="wert"(DOM-Eigenschaften setzen, z.B.[disabled]) - Event-Binding:
(event)="funktion()"(Auf Aktionen reagieren, z.B.(click)) - Two-Way-Binding:
[(ngModel)]="var"(Beidseitige Synchronisation für Formulare)
5. Modernes Control Flow (ab Angular 17)
Die neue Syntax orientiert sich an JavaScript, ist schneller und benötigt keine extra Importe.
@for mit @empty (Die 3D-Druck-Warteschlange)
Das track-Attribut ist jetzt Pflicht für extrem schnelle DOM-Updates.
<h3>Druckaufträge (Bambu Lab P1S)</h3>
<ul>
@for (print of printQueue; track print.id) {
<li>
{{ print.filename }} - Filament: {{ print.material }} ({{ print.progress }}%)
</li>
} @empty {
<li>Keine Druckaufträge in der Warteschlange. Zeit für ein neues Projekt!</li>
}
</ul>
@if / @else if / @else
@if (hotendTemp > 220) {
<p class="warning">Achtung: Düse ist sehr heiß!</p>
} @else if (hotendTemp > 50) {
<p>Düse kühlt ab... Bitte warten.</p>
} @else {
<p>Düse ist sicher und kann gewechselt werden.</p>
}
6. Fortgeschrittenes Beispiel: HTTP User-Datenabruf
// user.service.ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
@Injectable({ providedIn: 'root' })
export class UserService {
constructor(private http: HttpClient) {}
getUser(id: number) {
return this.http.get<any>(`https://api.test.de/users/${id}`);
}
}
// user.component.ts
export class UserComponent implements OnInit {
user: any;
constructor(private userService: UserService) {}
ngOnInit() {
this.userService.getUser(1).subscribe(res => this.user = res);
}
}