01. Oktober 2021

| Timm Rose

Single-Page-Application mit Angular

01. Oktober 2021

| Timm Rose

Single-Page-Application mit Angular

1. Setup

Node

Für die Installation von Angular und weiterer Pakete wird der Node Package Manager (npm) benötigt. Npm installierst du zusammen mit Node und kann hier runtergeladen werden: Node Download

Nach der Installation kannst du die Versionen von Node und npm mit folgenden Befehlen testen

$ node --version
$ npm --version

Angular

Um Angular zu installieren, wechselst du in das Projektverzeichnis und installierst als erstes Angular zusammen mit der CLI (CLI: siehe 2. Basics) global

$ npm install -g @angular/cli

Theme

Das Theme der GeoCity App ist ein schlankes Bootstrap-Theme des Anbieters CreativeTim. Ich nutze das von Angular Architects angebotene NPM-Paket (NPM – Node Package Manager) zum Paper-Design. Mit folgendem Befehl kannst du es per npm ganz einfach installieren

ng add @angular-architects/paper-design

Repository zur Geo-City App

Unter folgender URL ist das Repository der Geo-City zu finden, die in hier als Beispiel-Anwendung verwendet wird

https://gitlab.com/digitalerundschau/geo-city

2. Basics

CLI

ng new

Die Angular CLI (Command Line Interface) ist ein Kommandozeilentool, das die Konfiguration, das Bootstrapping, sowie Build- und Testzyklen mit recht simplen Befehlen erledigt. Ein Angular CLI Cheat Sheet mit allen Befehlen folgt demnächst und wird wieder als PDF zum Download veröffentlicht.

Der erste Befehl, den ich hier nutze, ist ng new für das Erstellen einer neuen Anwendung.

Für diese Angular Referenz setze ich eine Geo-City ein, die Entfernungen von Städten zueinander anzeigt. Ausgegeben werden die Daten in einer Tabelle in der nach eingegebener Stadt sortiert wird.

$ ng new geo-city

Mit ng new wird also ein neues Projekt initialisiert, geo-city ist der selbst gewählte Name der Anwendung.

Bei diesem Schritt wird gleichzeitig ein Git Projekt und Webpack aufgesetzt, sowie viele weitere Pakete, Plugins und kleinere Frameworks.

Projekt

Die Struktur mit Projekt-Rootverzeichnis sollte nun so aussehen:

Verzeichnis/DateiBeschreibung
src/Projekt-Sourcedateien
src/app/Anwendung mit Komponenten, Services, Interfaces …
src/assets/Assets-Verzeichnis für Logo, Images, JSON …
src/environment/Konfiguration des Prod und Dev Environments
src/index.htmlzentrale Page, enthält Root-Module, Bundle Referenzen, Stylesheet-Referenzen …
src/main.tszuerst ausgeführte Datei nach Anwendungsstart
src/scssglobale Stylesheet-Datei in SCSS beschreibbar
dist/Bundles für den Production Build (Production Server)
node_modules/npm Module (TS Compiler, Build Tools, Libraries) die per npm install installiert wurden
tsconfig.jsonKonfigurationen des TS Compilers
.browserslistrcListe der zu unterstützenden Browser für CSS-Präfixe
package.jsonReferenzen und Dependencies der installierten Libraries

Die einzelnen Komponenten, zum Beispiel die initiale App-Component, enthalten immer eine <name>.component.ts für die Programmlogik, bzw. das Verhalten, eine <name>.component.html für das Markup zur Darstellung, eine <name>.component.scss für die Styles des Markups und eine <name>.component.spec.ts für die Implementierung der Test-Cases.

Außerdem enthält die App-Component ein Module. Das app-module enthält die Declarations, die alle verwendbaren Komponenten des Moduls importiert, die Imports zum importieren sämtlicher benötigter Module wie BrowserModule (zur Ausführung von Angular im Browser) oder das FormsModule (zur Nutzung von Formularen), Providers zum registrieren von globalen Services und die Bootstrap Eigenschaft, die zum Aufruf der beim Start ausführbaren Komponente genutzt wird.

ng serve

Die Anwendung existiert bereits. Nun musst du lediglich einen lokalen Development-Server starten, um die Anwendung im Browser testen zu können.

Mit dem ng serve Befehl wird die Anwendung lokal im Development-Mode gebaut

ng serve

und ohne weitere Parameter über den Standardport 4200 lokal über deinen Loopback zur Verfügung gestellt

http://localhost:4200

Weitere Parameter könnten -o (ng serve -o) für das Öffnen der Anwendung im Standardbrowser, oder –port (ng serve –port 4201) für das Routen über einen alternativen Port sein.

Hier sind einige weitere Befehle der Angular CLI

ng add zum Hinzufügen von Paketen oder ganzen Libraries, hier der das Paket für den PWA (Progressive Web App)-Support

$ ng add @angular/pwa

ng build für das Generieren des Produktiv-Builds

$ ng build

ng generate für das Generieren diverser Schematics wie Komponenten, Interfaces, Services, Pipes usw.

$ ng generate component city-search

ng test startet die Unit Tests des gesamten Projektes

$ ng test

Git Repository

Möchtest du dein lokales Git Repository remote versionieren, in meinem Beispiel über ein Remote Repository unter Gitlab, sind folgende Schritte nötig:

1. Wechsel in dein eben erstelltes Projektverzeichnis

$ cd geo-city

2. Initialisiere das lokale Repository mit dem Branchnamen main

$ git init --initial-branch=main

3. Synchronisiere dein lokales mit dem remote Repository. Der URL-Platzhalter enthält die URL deines Gitlab Projektes (u.A. unter dem Clone Button zu finden)

$ git remote add origin <URL>

4. Füge die ersten Änderungen dem Index hinzu

$ git add .

5. Erstelle den ersten Commit

$ git commit -m "Initial commit"

6. Und pushe als letzten Schritt die Änderungen in den main-Branch des Remote Repositories

$ git push -u origin main

Bei Fragen zur Versionierung mit Git findest du unter Git Grundlagen und die 14 wichtigsten Befehle einen guten Einstieg.

Komponenten, Direktiven, Pipes

Komponenten erstellen

Angular arbeitet komponentenbasiert und wird schon während des Scaffoldings sehr modular aufgebaut.

So kannst du zwar auch ganze Seiten einer Anwendung, zum Beispiel eine Seite „Über uns“ (About), mit einer Komponente lösen, aber auch nur einen einzelnen Button oder eine Checkbox.

Genau das ist auch die Empfehlung, denn

Die erste Komponente ist eine Suche, mit der die Entfernungen von Städten angezeigt werden

$ ng generate component city-search

Die Kurzform kannst du auch verwenden, ist beim Erstellen mehrerer Komponenten sehr hilfreich

$ ng g c city-search

Damit sollten uns im Verzeichnis src/app/city-search vier Dateien vorliegen:

city-search.component.html – die so genannte View der Komponente
city-search.component.scss – die Stylesheet-Datei, in diesem Fall in SCSS
city-search.component.spec.ts – die Datei für Unit Tests
city-search.component.ts – die TypeScript-Klasse, sie enthält die Programmlogik

Direktiven

Direktiven sind ein Mittel zur Datenbindung, die der Komponente Verhalten hinzufügt. Die Direktiven ngFor, ngIf, ngStyle, ngClass und ngModel werden zur Verfügung gestellt.

Für die GeoCity-App beginne ich die Iteration über das distance Objekt mit der ngFor Direktive, die gleichbedeutend mit der For-Schleife ist

<table class="table table-striped">
  <tr *ngFor="let d of distance">
    <td>
      {{ d.id }}
    </td>
    <td>
      {{ d.start }}
    </td>
    <td>
      {{ d.end }}
    </td>
    <td>
      {{ d.date }}
    </td>
  </tr>
</table>

Ein Beispiel für die ngClass Direktive ist die Abfrage nach einem Boolean, sodass im true-Fall eine CSS-Klasse generiert wird.

Die CSS-Klasse kannst du dann spezifisch für die city-search Komponente in der city-search.component.scss formatieren

<tr [ngClass="{ 'active': d === selectedDistance }"]>
  ...
</tr>

Pipes

Mit den Angular Pipes gibt es eine sehr einfache Möglichkeit, die gebundenen Daten zu formatieren. Die Date-Pipe formatiert z. B. ein Datum in ein gewünschtes Format, in diesem Fall DD.MM.YYYY, HH:MM

<td>{{ distance.date | date:'dd.MM.Y, hh:mm'}}</td>

Eine weitere nützliche Pipe ist die Json-Pipe. Damit sind Ausgaben des Objekts in eine Json-Darstellung möglich.

<td>{{ distance | json }}</td>

Weitere Pipes sind in der Angular Dokumentation zu finden.

Binding

Interpolation

In Angular wird die Interpolation von Eigenschaften mit doppelt geschweiften Klammern geschrieben. Möchtest du zum Beispiel eine Eigenschaft title in der Komponenten initialisieren

export class AppComponent {
  title = 'Geo City';
}

kannst du sie im HTML per Interpolation ausgeben

<h1>{{ title }}</h1>

Event-Binding

Das Binden an DOM-Events bezeichnet man als Event-Binding, bei dem das Event in runde Klammern und danach die auszuführende Methode geschrieben wird.

Beim Event-Binding werden Handler für Ereignisse definiert, die wiederum in den Child-Komponenten erscheinen.

<button (click)="search()">Suche</button>

Property-binding

Bei Property-bindings werden Eigenschaften der Komponente in das Markup übergeben. Daten werden immer nur von der Parent zur Child Komponente (von oben nach unten) weitergegeben.

Im folgenden Beispiel wird dem Button das Attribut disabled gesetzt, wenn die Eigenschaft start leer ist.

<button [disabled]="!start">Suche</button>

Two-way-binding

Beim Two-way-binding wird nicht nur der Wert einer Eigenschaft übernommen, der Wert kann z. B. über ein input Formular angepasst und wieder in die Komponente zurückgeschrieben werden.

Im folgenden Beispiel wird der initiale Wert der Eigenschaft start in das input übernommen. Bei Eingabe eines neuen Stadtnamens wird dieser in die Komponente geschrieben und für die Suche verwendet.

<input [(ngModel)]="start" name="start">

Digitale Rundschau Logo

© 2021 Digitale Rundschau | Impressum