Googles beliebtes Single-Page-Application-(SPA-)Framework AngularJS wurde mit Version 2 komplett neu in TypeScript geschrieben. Damit ist auch das JS-Suffix aus dem Namen entfallen, und das Framework heißt seitdem einfach nur Angular. Angular-Anwendungen werden mit Komponenten gebaut, die sich ineinander verschachteln lassen. Zum Entwickeln einer Angular-Anwendung hat sich TypeScript als Standardsprache etabliert. In diesem Artikel wird eine Angular-Anwendung von Grund auf erstellt, mit allem, was dazugehört: Listen, Data Bindings und einer Verbindung zu GitHub via REST-API. Beim Entwickeln dieser Anwendung tauchen viele bekannte Muster der Sprache TypeScript auf: Klassen, Interfaces, Module oder Decorator.
Das Team von Google ist mit Angular auf eine semantische Versionierung umgestiegen. Die in diesem Artikel verwendete Version ist die zum Zeitpunkt der Drucklegung aktuelle Version 4. Die mit Version 2 eingeführten Grundprinzipien wie Komponenten, Data Bindings, Services usw. bleiben erhalten. Um eine Angular-Anwendung zu erstellen, wird das Angular-CLI genutzt, wobei CLI für Command Line Interface steht.
Von Thomas Claudius Huber gibt es auf www.tutorials.entwickler.de auch ein ausführliches Videotutorial zur Einführung in TypeScript.
Das Angular-CLI wird über den Node Package Manager (NPM) mit folgendem Befehl global installiert: npm install -g @angular/cli.
Mit dem installierten CLI lässt sich jetzt die Kommandozeile nutzen, um ein neues Projekt zu erstellen und in diesem Projekt Komponenten, Services und vieles mehr zu generieren. Zum Erstellen einer App wird auf der Kommandozeile der jetzt verfügbare ng-Befehl wie folgt genutzt: ng new github-browser.
github-browser stellt im oberen Beispiel den Namen der App dar. Die App selbst wird in einem Unterordner mit demselben Namen erstellt. Das heißt, via change directory-Befehl (cd) kann von der Kommandozeile einfach in diesen Ordner gewechselt werden: cd github-browser.
Der Ordner enthält nicht nur ein neues, leeres Projekt, sondern bereits eine lauffähige Anwendung mit zahlreichen Beispieldateien. Bevor die Anwendung gestartet wird, sollten noch alle in der package.json-Datei vermerkten Node-Module installiert werden. Dazu einfach auf der Kommandozeile den aus dieser Artikelserie bereits bekannten Befehl aufrufen: npm install.
Mit den installierten Node-Modulen steht einem Start nichts mehr im Wege. Zum Starten der Anwendung wird auf der Kommandozeile der Befehl ng serve ausgeführt. Dieser Befehl startet einen Webserver auf dem Port 4200. Somit lässt sich die Website bzw. die Angular-App nach dem Ausführen dieses Befehls auf http://localhost:4200 öffnen. Der Webserver beobachtet nebenbei auch die Dateien des Projekts. Bei einer Änderung an einer Datei wird die Anwendung neu gebaut und der Browser automatisch aktualisiert.
Anstatt die App unter http://localhost:4200 manuell zu öffnen, lässt sich ng serve auch wie folgt mit dem --open-Parameter ausführen: ng serve --open.
Dadurch wird automatisch ein Browserfenster mit der lauffähigen App geöffnet. Die mit dem CLI generierte App sieht wie in Abbildung 1 aus.
Die generierte App besitzt eine ganze Palette an Dateien, die für eine „Real-World“-Anwendung sehr nützlich sind. Beispielsweise gibt es bereits eine karma.conf.js-Datei, die als Konfiguration für Unit-Tests dient, oder protractor.conf.js, das für End-to-End-Tests eingesetzt wird. Einen Überblick aller Dateien des generierten Projekts gibt es im Quickstart der offiziellen Angular-Dokumentation [1]. Für eine einfache App, wie sie in diesem Artikel erstellt wird, sind diese Dateien nicht notwendig. In diesem Abschnitt werden daher lediglich folgende Dateien aus dem src-Ordner des Projekts beschrieben, die die zentralen Teile einer Angular-App darstellen:
app/app.component.ts
app/app.component.html
app/app.module.ts
main.ts
index.html
Neben diesen Dateien befinden sich im Projekt natürlich auch altbekannte Dateien, wie package.json oder tsconfig.json. Los geht’s mit einem Blick auf die Datei app.component.ts, die in Listing 1 dargestellt ist. Diese Datei enthält die Komponente, die beim Starten der Angular-App geladen wird. Am Anfang der Datei wird der Component-Decorator aus dem @angular/core-Modul importiert. Die Datei enthält dann die Klasse AppComponent, die eine title-Property besitzt und mit dem export-Schlüsselwort aus dieser Datei bzw. diesem Modul exportiert wird. Die AppComponent-Klasse ist mit dem importierten Component-Decorator dekoriert. Das an den Component-Decorator übergebene Objekt – auch als „Metadaten“ einer Komponente bezeichnet – enthält in Listing 1 eine selector-Property. Darüber wird der HTML-Tag festgelegt, mit dem sich diese Komponente referenzieren lässt. In Listing 1 ist dies der Tag app-root.
Die beiden Properties templateUrl und und styleUrls zeigen auf zwei Dateien, die neben der app.component. ts-Datei generiert wurden. Ein Ausschnitt der app.component.html-Datei ist in Listing 2 dargestellt. Diese Datei definiert das Aussehen der Komponente, während die Klasse die Logik hat. Wie in Listing 2 zu sehen, wird mit einem doppelten geschweiften Klammernpaar an die title-Property der AppComponent-Klasse gebunden.
Listing 1: „app.component.ts“
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app';
}
Listing 2: „app.component.html“
<div style="text-align:center">
<h1>
Welcome to {{title}}!
</h1>
<img width="300" src="...">
</div>
Anstatt das Template für eine Komponente via templateUrl-Property einer separaten HTML-Datei zu definieren, lässt sich das Template auch direkt im Component-Decorator über die template-Property setzen. Dies ist insbesondere dann hilfreich, wenn es sich um ein kleineres Template handelt. Listing 3 zeigt dies anhand der app.component.ts-Datei. Jetzt wird auch auf einen Blick deutlich, dass im Template an die title-Property der AppComponent-Klasse gebunden wird.
Listing 3: „app.component.ts“
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: '<h1>Welcome {{title}}</h1>'
})
export class AppComponent {
title = 'Windows Developer';
}
Listing 4 zeigt die index.html-Datei des generierten Projekts. Innerhalb des body-Tags wird der app-root-Tag verwendet, um an dieser Stelle die AppComponent zu erzeugen und anzuzeigen.
Listing 4: „index.html“
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>GithubBrowser</title>
<base href="/">
...
</head>
<body>
<app-root></app-root>
</body>
</html>
Die Selektoren für Komponenten – wie in Listing 4 app-root – sollten immer einen Bindestrich enthalten. Dadurch wird sichergestellt, dass es auch in Zukunft nicht zu Namenskollisionen mit Standard-HTML-Tags kommt. Denn die HTML-Spezifikation sieht vor, dass alle Standard-HTML-Tags keine Bindestriche enthalten.
Neben den Dateien app.component.ts und index. html gibt es noch zwei sehr wichtige, zentrale Dateien in einem Angular-Projekt. Listing 5 zeigt die Datei app. module. ts. Darin ist das Hauptmodul der Anwendung definiert. Ein Modul ist dabei ein Angular-spezifisches Konzept, um den eigenen Code innerhalb der App zu gruppieren und zu strukturieren. Damit es nicht zur Verwirrung mit TypeScript bzw. ECMA-Modulen kommt, werden die Angular-Module im Folgenden als NgModule bezeichnet. Ein NgModule ist eine einfache Klasse – in Listing 5 die Klasse AppModule – die mit dem NgModule-Decorator ausgestattet ist. Dieser Decorator nimmt ein Objekt entgegen, mit dem sich via declarations-Property Komponenten an das NgModule anhängen lassen. Via bootstrap-Property werden die Komponenten angegeben, die zum Start eingesetzt werden. In Listing 5 ist dies die AppComponent. Eine Komponente kann in Angular immer zu genau einem NgModule gehören, nicht zu mehreren. Neben Komponenten kann ein NgModule auch andere NgModules importieren. Dies geschieht über die imports-Property, die...