Dieser Kurs setzt ein Angular-Front-End vor die Kladde-API aus K2. Sie kennen C#, ASP.NET Core, Web-APIs, Anmeldung mit Entra ID und Tests (K2 2.2, 2.3, 2.6, 2.7, 2.12) und lernen Angular
von Null, mit dem Blick dessen, der die API geschrieben hat. Diese Lektion legt das Projekt web/kladde-angular an, zeigt, was die CLI erzeugt, hängt den Dev-Server an die API und klärt eine
Frage für den ganzen Kurs: Muss strict in der tsconfig.json stehen? TypeScript selbst lehrt der Kurs nicht (K2 2.2).
Stand der Prüfung. Ausgeführt wurde mit Node 24.22.3 und Angular CLI 22.2.7:
ng newmit--skip-install(in zwei Fassungen),ng generate componentundng generate service,ng build(Exit-Code 0, bei absichtlichen Fehlern 1),ng test --no-watchmit Vitest (Exit-Code 0, 2 Tests, im Projekt von 0102) und ein kurzerng servemit Proxy gegen einen kleinen HTTPS-Testserver auf Port 7180 (curl: 200, ohnesecure: false502). Die Pakete installierte ein Referenzprojekt mit byte-gleicherpackage.json. Nicht ausgeführt: die Anlage mit Paketinstallation in einem Zug, das Schlüsselpaar vondotnet dev-certs, die echte Kladde-API, ein Browser, der Test aus Übung 1 nach Ihrer Änderung. Fakten zu Fassungen stammen von angular.dev (gelesen am Schreibtag); was nicht gelesen wurde, steht als offen da.
Was Angular für Sie ist
Angular ist ein Framework mit Vorgaben: Es bringt Werkzeug (CLI, Build, Test), eine feste Projektform, Abhängigkeitsinjektion, Router, HTTP-Client und Formulare mit. Für eine .NET-Entwicklerin liest
sich das vertraut: Dienste kommen per inject() an, app.config.ts ist das Gegenstück zu Program.cs, und die CLI erzeugt Dateien wie dotnet new. Der Preis: Sie lernen die Vorgaben, bevor Sie
schnell sind. Es lohnt sich bei einer größeren Oberfläche mit mehreren Menschen; für eine kleine Seite genügt oft Blazor (K2 2.5).
Ein Angular-Programm besteht am Ende aus statischen Dateien (HTML, JavaScript, CSS), die im Browser laufen und die API per HTTP aufrufen. Alles im Bundle ist öffentlich; ein Geheimnis gehört nie hinein.
Fassungen und Unterstützungsfenster
Die Seite der Releases (angular.dev/reference/releases) nennt am Lesetag die Hauptfassung 22 (@angular/core 22.2.6; die Dokumentation trägt „Built at v22.2.6“). Je Jahr kommt ein Hauptsprung, jede
Fassung ist 12 Monate aktiv und 12 Monate in der Langzeitpflege (LTS). Fassung 21 ist in der Langzeitpflege, die von 20 endet bald; die Daten stehen auf der Seite.
Die Seite der Versionen (angular.dev/reference/versions) nennt für Angular 22 Node ^22.22.3 || ^24.15.0 || ^26.0.0 und TypeScript >=6.0.0 <6.1.0.
Der Kurs nimmt Node Linie 24. Prüfen Sie die Fassung vor jeder Anlage (die Maschine des Schreibens hatte als Standard 22.12.0, dafür meldet npm Warnungen; alle Läufe hier nutzten 24.22.3):
node --version
npm --version
Nicht verwechseln: K2 baut die API-Seite mit TypeScript 7 über NuGet, ein anderes Projekt. npm ist hier nur das Werkzeug von Angular.
Die CLI und das Projekt anlegen
Die CLI heißt ng: ng new legt an, ng serve startet den Dev-Server, ng build baut, ng generate erzeugt Dateien, ng test testet. Aus ng new --help (22.2.7) lesen wir die Optionen, die für uns zählen:
--routing, --style=scss (unsere Regel), --prefix (Vorsilbe der Selektoren, Standard app), --strict (Standard an), --zoneless, --test-runner (vitest Standard, karma),
--file-name-style-guide (2025 Standard mit app.ts, 2016 mit app.component.ts), --skip-git, --skip-install und --ai-config (none lässt Dateien für KI-Werkzeuge weg). Im Ordner web des
Kladde-Repositorys (dort gibt es schon ein Git-Repository):
npx @angular/cli@22 new kladde-angular --routing --style=scss --prefix=kl --skip-git --ai-config=none
Beim Schreiben lief derselbe Befehl mit Fassung 22.2.7 und zusätzlich --skip-install; er erzeugte (ohne README.md,
.editorconfig, .gitignore, .vscode/*, app.spec.ts, app.scss):
CREATE kladde-angular/.prettierrc (173 bytes)
CREATE kladde-angular/angular.json (2134 bytes)
CREATE kladde-angular/package.json (789 bytes)
CREATE kladde-angular/tsconfig.json (939 bytes)
CREATE kladde-angular/tsconfig.app.json (412 bytes)
CREATE kladde-angular/tsconfig.spec.json (423 bytes)
CREATE kladde-angular/src/main.ts (228 bytes)
CREATE kladde-angular/src/index.html (310 bytes)
CREATE kladde-angular/src/styles.scss (81 bytes)
CREATE kladde-angular/src/app/app.ts (309 bytes)
CREATE kladde-angular/src/app/app.html (20488 bytes)
CREATE kladde-angular/src/app/app.config.ts (322 bytes)
CREATE kladde-angular/src/app/app.routes.ts (80 bytes)
CREATE kladde-angular/public/favicon.ico (15086 bytes)
Die Namen ohne .component folgen der Seite „Style Guide“: App liegt in app.ts, app.html, app.scss, ohne Suffix.
src/main.tsstartet mitbootstrapApplication(App, appConfig).src/app/app.config.tsist die Konfiguration beim Start, eine Liste vonproviders(die Vorlage setztprovideBrowserGlobalErrorListeners()undprovideRouter(routes)). Hier kommenprovideHttpClient(...)(0202) und die Anmeldung (0301) dazu.src/app/app.tsist die Wurzelkomponente (imports: [RouterOutlet],selector: 'kl-root');app.htmleine Platzhalterseite von 20 KB, die Sie in der Übung ersetzen;app.routes.tshält die Routen (leer; 0201).angular.jsonbeschreibt die Zielebuild,serve,test. Der Build nutzt@angular/buildmit dem Builderapplication;inlineStyleLanguagesteht aufscss.tsconfig.json,tsconfig.app.json(schließt*.spec.tsaus) undtsconfig.spec.json(vitest/globals) konfigurieren TypeScript.package.jsonnennt Skripte und Abhängigkeiten, ohnezone.js(unten);package-lock.jsongehört ins Repository, mit ihr holtnpm ciüberall dieselben Pakete.public/wird unverändert ausgeliefert;src/index.htmlist die eine Seite mit<kl-root></kl-root>. Dort ändern Sie sofort<html lang="en">zulang="de"(Screenreader wählen danach die Sprache) und den<title>aufKladde.
Standardläufer der Tests ist Vitest; Prüfläufe: ng test --no-watch, Exit-Code lesen (0401).
Strict: gehört es ausdrücklich in die tsconfig?
Unsere Regel: TypeScript ist strict. Die erzeugte tsconfig.json enthält aber kein "strict": true; unter compilerOptions stehen noImplicitOverride, noPropertyAccessFromIndexSignature,
noImplicitReturns und noFallthroughCasesInSwitch, unter angularCompilerOptions strictInjectionParameters und strictInputAccessModifiers. Ist das Projekt dann nicht strict?
Der Versuch, in einer Kopie mit TypeScript 6.0.3: App bekam eine Methode mit text.length bei text: string | undefined und ein Feld leer: string = null. Vier Läufe von ng build:
| Lauf | tsconfig.json |
Ergebnis |
|---|---|---|
| 1 | wie erzeugt, ohne strict |
Exit-Code 1: TS18048: 'text' is possibly 'undefined' und TS2322: Type 'null' is not assignable to type 'string' |
| 2 | mit "strict": true |
Exit-Code 1, dieselben zwei Fehler |
| 3 | mit "strict": false |
Exit-Code 0, derselbe Code |
| 4 | wie erzeugt, Template mit [anzahl]="'drei'" für ein input.required<number>() |
Exit-Code 1: TS2322: Type 'string' is not assignable to type 'number' |
Ergebnis: Mit dieser Vorlage und TypeScript 6.0.3 ist die strenge Prüfung auch ohne den Eintrag an, bis "strict": false sie abschaltet. Die Seite „tsconfig“ von typescriptlang.org nennt für strict
den Standard true (gelesen); zu einer Änderung in 6.0 sagt sie nichts, die Beobachtung gilt für 6.0.3. ng new --no-strict schreibt in der erzeugten Datei "strict": false und "strictTemplates": false.
Entscheidung für den Kurs: Wir schreiben "strict": true nicht zusätzlich hinein; es ändert das Ergebnis nicht. Stattdessen gilt die Probe aus Übung 1 in jedem Projekt dieses Kurses: In den
tsconfig-Dateien steht kein "strict": false, und ein absichtlicher Fehler bricht den Build. Wer ein Projekt mit --no-strict erbt oder die TypeScript-Fassung wechselt, hält die Regel mit einer Zeile fest.
SCSS und ng generate
--style=scss stellt Komponenten (app.scss) und die globale src/styles.scss auf SCSS um; das gilt im ganzen Kurs. Erzeugt wird mit ng generate:
npx ng generate component kontakte/kontakt-liste
npx ng generate service kontakte/kontakt-daten
CREATE src/app/kontakte/kontakt-liste/kontakt-liste.spec.ts (597 bytes)
CREATE src/app/kontakte/kontakt-liste/kontakt-liste.ts (222 bytes)
CREATE src/app/kontakte/kontakt-liste/kontakt-liste.scss (0 bytes)
CREATE src/app/kontakte/kontakt-liste/kontakt-liste.html (29 bytes)
CREATE src/app/kontakte/kontakt-daten.spec.ts (366 bytes)
CREATE src/app/kontakte/kontakt-daten.ts (88 bytes)
Die Komponente bekommt den Selektor kl-kontakt-liste und die Klasse KontaktListe, der Dienst KontaktDaten den Decorator @Service(). Die Seite „Creating and using services“ nennt ihn eine Kurzform für
@Injectable({ providedIn: 'root' }) und trägt dazu keinen Vermerk „neu“ oder „Vorschau“; wir nehmen, was die CLI erzeugt. Die Ordner kontakte, termine, buchung, shared und core unter src/app sind
feste Namen der Kladde.
Zoneless in einem Absatz
Die Seite „Zoneless“ sagt: „Zoneless is the default in Angular v21+“, ohne die Bibliothek zone.js. Darum hat die Vorlage kein
zone.js in package.json und kein polyfills in angular.json. Angular prüft Ansichten auf Meldungen hin, nach der Seite etwa wenn ein im Template gelesenes Signal sich ändert, ein Ereignis-Listener im
Template feuert oder markForCheck gerufen wird. Wer Signals benutzt (0102), muss nichts weiter tun.
Dev-Server und Proxy zur API
ng serve liefert auf http://localhost:4200 aus, bei jeder Änderung neu gebaut. Die Kladde-API läuft auf https://localhost:7180 (Stand K2 prüfen). Ruft der Browser von Port 4200 aus Port 7180 auf, verlangt
er CORS-Freigaben (0302). In der Entwicklung umgehen Sie das mit einem Proxy: Der Dev-Server nimmt alles unter /api entgegen und leitet es weiter; der Browser sieht nur Port 4200. Die Datei
proxy.conf.json im Projektordner:
{
"/api/**": {
"target": "https://localhost:7180",
"secure": false
}
}
Eingehängt wird sie im Ziel serve von angular.json (neben configurations):
"options": {
"proxyConfig": "proxy.conf.json"
},
Nach der Seite „Serve“ passt /api/** auf /api, /api/users und /api/users/123, aber nicht auf /api-docs; Änderungen an der Datei brauchen einen Neustart von ng serve. Zur Wirkung von
secure sagt die Seite nichts. Beobachtet: Der Testserver auf 7180 benutzte ein selbst ausgestelltes TLS-Schlüsselpaar. Mit "secure": false antwortete curl.exe http://localhost:4200/api/contacts mit 200 und
dem JSON des Testservers (via zeigte /api/contacts?page=1&size=20); ohne die Zeile antwortete der Dev-Server mit 502 Bad Gateway. Wie sich das Schlüsselpaar von dotnet dev-certs https verhält, wurde
nicht geprüft (offen): Meldet der Proxy 502, ist secure: false der erste Verdacht.
Übung 1
Projekt anlegen, starten, ändern, strict belegen.
- Prüfen Sie
node --version(Linie 24) und legen Sie im Ordnerwebdas Projekt mit dem Befehl aus dem Text an. - Ändern Sie in
src/index.htmllangaufdeund den<title>aufKladde. - Ersetzen Sie
src/app/app.htmldurch<main><h1>Kladde</h1></main>und streichen SieRouterOutletausimportsinapp.ts(sonst meldet der Build ihn womöglich als ungenutzt; nicht geprüft). - Legen Sie
proxy.conf.jsonan und tragen SieproxyConfiginangular.jsonein. - Starten Sie die Kladde-API (Stand K2 prüfen) und
npx ng serve. Öffnen Siehttp://localhost:4200/undhttp://localhost:4200/api/contacts?page=1&size=20. Ändern Sie die Überschrift und sehen Sie die Seite neu laden. - Passen Sie
app.spec.tsan (toContain('Kladde')stattHello, kladde-angular), dannnpx ng buildundnpx ng test --no-watch, jeweils mit gelesenem Exit-Code. - Die Probe: Fügen Sie
app.tsprotected laenge(text: string | undefined): number { return text.length; }hinzu und bauen Sie. Setzen Sie dann"strict": falsein dietsconfig.json, bauen Sie noch einmal und nehmen Sie beides wieder heraus.
So prüfen Sie: Die Seite zeigt „Kladde“; der zweite Aufruf zeigt das JSON der API (contacts, total, page, pageCount). Bau und Test enden mit 0. Die Probe: erster Bau Exit-Code 1 mit TS18048,
zweiter Exit-Code 0.
Lösung 1
- Fehler zu
proxy.conf.jsonoder/api/...landet in 404: Pfad inangular.jsonund JSON-Syntax prüfen,ng serveneu starten. - Der Browser zeigt 502: Die API läuft nicht, hört auf einem anderen Port, oder der Proxy mag ihr Schlüsselpaar nicht (
secure: falsefehlt). - Der Test scheitert mit
Hello, kladde-angular: Er prüft noch den Text der Platzhalterseite (Schritt 6). - Die Probe baut beim ersten Mal grün: Suchen Sie in allen drei
tsconfig-Dateien nachstrict; ein Eintrag in der App-Datei überschreibt den der Hauptdatei. Das Projekt ist dann nicht strict.
Was Sie jetzt können
- Sie sagen, was Angular einer API-Entwicklerin bietet, und lesen Fassung, Node-Bereich und Unterstützungsfenster auf der Seite nach, statt sie zu raten.
- Sie prüfen Node 24, legen
web/kladde-angularan, bauen, starten und testen es und lesen jeweils den Exit-Code. - Sie benennen
main.ts,app.config.ts,app.ts,angular.jsonundtsconfig.jsonund erzeugen Dateien mitng generate. - Sie hängen den Dev-Server mit
proxy.conf.jsonanhttps://localhost:7180;secure: falsegehört nur in die Entwicklung, in der Auslieferung gibt es keinen Proxy (0403). - Sie wissen, dass die Vorlage auch ohne Eintrag strict ist, und belegen es mit einem absichtlichen Fehler.
Weiterlesen
- Releases und Unterstützungsfenster: Hauptfassungen, aktive und Langzeitpflege.
- Versionen: Node und TypeScript je Angular-Fassung.
- Dev-Server und Proxy:
proxyConfigund das Muster/api/**. - Zoneless: Standard seit Fassung 21 und was dafür zählt.
- Style Guide: Dateinamen,
protected,readonly,inject(). - tsconfig: strict: was die Familie der strengen Optionen einschaltet.
Die Kladde: Das Gerüst web/kladde-angular steht mit Präfix kl, SCSS, Vitest und Proxy zur API. Als Nächstes bauen Sie die Kontaktliste aus festen Daten (0102).