Suche
Teil 1: Erste Schritte mit Angular 2 und TypeScript

Angular 2 Tutorial: Moderne Frontends für alle Plattformen entwickeln

Manfred Steyer

(c) Shutterstock / gdainti

Dieses dreiteilige Angular-2-Tutorial von W-JAX Speaker Manfred Steyer vermittelt den Einstieg in die Arbeit mit dem JavaScript Framework für Webanwendungen. In Teil 1 geht es um die Grundlagen und die ersten Schritte mit TypeScript.

Dieses Angular 2 Tutorial beschäftigt sich mit dem Aufbau einer Single-Page-Anwendung mit Angular 2 und TypeScript. Der Single-Page-Ansatz erlaubt die Entwicklung von webbasierten Frontends, die auf sämtlichen klassischen und mobilen Plattformen laufen und durch den Einsatz von JavaScript einen hohen Grad an Benutzerfreundlichkeit bieten. Das Framework Angular 2 unterstützt das und ermöglicht das Erreichen einer hohen Codequalität mit bewährten Konzepten, wie Komponentenorientierung und Dependency Injection.

Das große Angular 2 Tutorial

Teil 1: Erste Schritte mit Angular 2 und TypeScript
Teil 2: Formulare und Validierung
Teil 3: Navigation mit dem Component Router

Erste Schritte mit Angular 2 und TypeScript

Moderne Weblösungen sind vor allem im Umfeld von Geschäftsanwendungen derzeit sehr populär, da sie auf allen vorherrschenden Plattformen laufen und durch JavaScript und CSS ein hohes Maß an Benutzerfreundlichkeit bieten. Diese so genannten Single-Page-Applikationen (SPA) weisen eine Architektur auf, die der von klassischen verteilten Anwendungen entspricht. Im Wesentlichen sieht sie einen Client vor, der Services via HTTP konsumiert. Diese haben wiederum Zugriff auf Unternehmensressourcen, wie Datenbanken oder ERP-Systeme. Das vorliegende Tutorial zeigt, wie sich eine solche moderne Cross-Plattform-Lösung entwickeln lässt. Hierzu wird die Erstellung einer SPA zum Buchen von Flügen beschrieben. Abbildung 1 gibt einen ersten Vorgeschmack darauf.

 

angular2-intro-solution

Abb. 1: Erstellung einer SPA zum Buchen von Flügen

Um die Komplexität der zugrunde liegenden Webtechnologien beherrschbar zu machen, kommt die neue Version 2 des populären JavaScript-Frameworks Angular (in Version 1 noch AngularJS genannt) zum Einsatz. Dieses stammt aus der Feder von Google und erfreut sich einer großen Community. Angular 2 ist seit Dezember 2015 in der Betaphase. Das bedeutet, laut Aussagen des Produktteams, dass sich die zugrunde liegenden Konzepte sowie der Kern nicht mehr ändern sollen. Nichtsdestotrotz kann es an den hier vorgestellten Aspekten bis zur finalen Veröffentlichung zu kleineren Änderungen kommen.

Zusätzlich nutzt dieses Tutorial die Sprache TypeScript, die auch das Angular-2-Team zum Entwickeln des Frameworks heranzieht. Sie bietet Möglichkeiten des aktuellen JavaScript-Standards ECMAScript 6, wie Klassen, Module und Lambda-Ausdrücke. Zusätzlich bietet TypeScript die Möglichkeit einer statischen Typisierung. Mithilfe des TypeScript-Compilers lässt sich der geschriebene Code in handelsübliches JavaScript (ECMAScript 5) überführen, das in jedem gängigen Browser läuft.

Angular im Videotutoriallogo-entwickler tutorials

Im entwickler.tutorial Angular – eine Einführung bereitet Sie Manfred Steyer auf die Entwicklung mit dem Angular Framework vor. Steyer zeigt anhand eines praxisnahen Beispiels, wie man Services und Dependency Injection integriert, Pipes zur Formatierung von Ausgaben nutzt, Komponenten mit Bindings verwendet und professionell mit dem Angular CLI umgeht.

Jetzt anmelden!

 

Angular 2 Tutorial: Projekt-set-up

Als Entwicklungsumgebung für den Start mit Angular 2 empfiehlt sich der leichtgewichtige Editor Visual Studio Code, der für Linux, Mac OS und Windows zur Verfügung steht und eine gute Unterstützung für TypeScript mit sich bringt. Mehr Komfort für die Entwicklung mit TypeScript und Angular 2 bietet das kostenpflichtige WebStorm von JetBrains. Es generiert beispielsweise import-Anweisungen und bietet Codevervollständigung auch im HTML-Markup.

Um hier keinen Platz mit dem Projekt-set-up zu verschwenden, sei an dieser Stelle auf das offizielle Angular-Seed-Projekt verwiesen. Die komplette Implementierung des in diesem Artikel beschriebenen Beispiels findet sich hier. Informationen bezüglich Build und Start der Beispiele finden sich jeweils in den beigelegten Readme-Dateien.

Eine Anwendung, eine Komponente

Angular 2 ist komponentenorientiert aufgebaut. Das bedeutet, dass die gesamte Anwendung eine Komponente ist. Diese so genannte Top Level Component besteht aus weiteren Komponenten, die wiederum aus weiteren Komponenten bestehen können. Somit ergibt sich ein Komponentenbaum, wie bei anderen UI-Frameworks auch.

Eine Angular-2-Komponente besteht aus zwei Teilen: einem Component Controller, der die Logik beinhaltet, und einem Template, das das Markup zur Darstellung bietet. Der Component Controller der hier beschriebenen Komponente, die das Suchen von Flügen erlaubt, findet sich in Listing 1. Es handelt sich dabei um eine TypeScript-Klasse, welche das UI auf abstrakter Ebene widerspiegelt.

import {Component} from '@angular/core';
import {Flug} from "../../entities/flug";
import {Http, URLSearchParams} from '@angular/http';
  
@Component({
    selector: 'flug-suchen', 
    templateUrl: 'app/flug-suchen/flug-suchen.html',
})
export class FlugSuchenComponent { 
    
  private http: Http;
    
  constructor(http: Http) {
    this.http = http;
  }
  
  von: String = "Graz";
  nach: String = "Hamburg";
  selectedFlug: IFlug;
  fluege: Array<IFlug> = [];
  
  search(): void { […] }
    
  select(flug: IFlug): void {
    this.selectedFlug = flug;
  }
  
}

Der Konstruktor lässt sich den von Angular 2 gebotenen HTTP-Service injizieren. Dabei handelt es sich um ein Objekt zum Zugriff auf Ressourcen, wie Web-APIs, via HTTP.

Die Eigenschaften von und nach repräsentieren die Flugroute, für die der Anwender Flüge suchen möchte. Das Array fluege nimmt die gefundenen Flüge auf. Es ist mit dem Interface Flug (Listing 2) typisiert, das die Struktur der von dem Web-API gelieferten Flugobjekte widerspiegelt. Da TypeScript auf strukturelle Typkompatibilität setzt (Kasten: „Strukturelle Typkompatiblität“) kann dieses Array die in Form von JSON empfangenen Objekte aufnehmen.

export interface Flug {
  id: number;
  abflugort: string;
  zielort: string;
  datum: string; 
  // Datum im ISO-Format
}

Die Methode search kümmert sich um das Abrufen der Flüge, und select notiert sich den vom Benutzer ausgewählten Flug. Durch die Angabe von Typen kann der TypeScript-Compiler Typverletzungen erkennen und mit einer Fehlermeldung abmahnen. Diese sind jedoch optional. Lässt der Entwickler sie weg, hat er eine astreine ECMAScript-6-Klasse, die vom TypeScript-Compiler in handelsübliches ECMAScript 5 übersetzt wird.

Lesen Sie auch: “Angular 2 wird sein ganzes Potential wohl erst in einigen Jahren entfalten können”

Das Annotieren der Klasse mit dem Decorator Component entspricht jedoch nicht dem ECMAScript-Standard. Genauer gesagt: Noch nicht, denn Decoratoren liegen als Vorschlag für die Weiterentwicklung von JavaScript vor und kommen auch schon heute in einigen Frameworks zum Einsatz. Außerdem unterstützen auch populäre ECMAScript-6-Transpiler wie Babel diese Spracherweiterung bereits seit längerer Zeit. Angular 2 nutzt Decoratoren, um Metadaten ins Spiel zu bringen. Dies entspricht dem Einsatz von Annotationen unter Java oder Attributen unter .NET.

Das gezeigte Beispiel gibt über den Decorator Component bekannt, dass die Klasse FlugSuchenComponent eine Komponente repräsentiert. Der angegebene CSS-Selektor identifiziert die HTML-Elemente, welche die Komponente repräsentieren. Innerhalb dieser Elemente rendert Angular 2 die Komponente. Der templateUrl verweist auf das Template mit dem Mark-up zum Darstellen der Komponente.

Zum Referenzieren von Konstrukten aus anderen Namensräumen kommt die Importanweisung im oberen Bereich von Listing 1 zum Einsatz. Bei diesen Namensräumen handelt es sich um eine Neuerung von ECMAScript 6. Anders als bei früheren JavaScript-Versionen, die standardmäßig alles im globalen Namensraum verstauen, hat ab ECMAScript 6 jede Datei einen eigenen Namensraum. Konstrukte, die auch außerhalb des Namensraums sichtbar sein sollen, werden mit export markiert. Ein Beispiel dafür ist die Klasse FlugSuchenComponent. Die Angabe von export class ist somit mit einer public class in Java vergleichbar. Um solche exportierten Konstrukte in anderen Namensräumen zu nutzen, sind sie mit import zu importieren. Diese referenziert die jeweilige Datei oder einen Namensraum, der programmatisch eingerichtet wurde. Ein Beispiel für Ersteres ist der Verweis auf ../../entities/flug. Ein Beispiel für Letzteres stellt der Verweis auf den Namensraum @angular/core, der sich u. a. in einem mit Angular 2 ausgelieferten Bundle befindet.

Strukturelle Typkompatibilität

Sprachen wie Java sehen vor, dass eine Klasse ein Interface explizit implementiert. Dies geschieht durch die Nennung des Interface im Rahmen der Klassendeklaration. Nur in diesem Fall kann eine Variable des Interfacetyps Objekte dieser Klassen aufnehmen.

Bei TypeScript ist das anders: Hier kommt strukturelle Typkompatibilität zum Einsatz. Somit kann eine Variable eines Interfacetyps jedes Objekt aufnehmen, dessen Struktur dem des Interface entspricht. Die Nennung des Interface im Zuge der Klassendeklaration ist optional. Allerdings gibt sie dem Compiler die Möglichkeit zu prüfen, ob die Klasse tatsächlich zum Interface kompatibel ist. Ist dem nicht so, merkt er dies mit einer Fehlermeldung an.

Auf Web-APIs zugreifen

Das Innenleben der Methode search findet sich in Listing 3. Sie nutzt das injizierte Objekt der Klasse Http zum Zugriff auf ein Web-API. Zum Abrufen von Daten über das HTTP-Verb GET kommt die gleichnamige Methode zum Einsatz. Diese nimmt den gewünschten URL sowie ein Objekt entgegen, das die Anfrage näher beschreibt. Über dieses Objekt kann der Aufrufer zum Beispiel die zu übersendenden Kopfzeilen, die Nutzdaten oder auch URL-Parameter angeben. Letzteres nutzt das gezeigte Beispiel, um über ein Objekt vom Typ URLSearchParams die Werte von und nach als URL-Parameter abflugOrt und zielOrt zu übergeben.

search(): void {
   
  var url = "http://www.angular.at/api/flug";
   
  var params = new URLSearchParams();
  params.set('abflugOrt', this.von);
  params.set('zielOrt', this.nach);
   
  this.http
    .get(url, { search: params })
    .map(resp => resp.json())
    .subscribe( 
    (fluege) => {
      this.fluege = fluege;
    },
    (err) => {
      console.debug(err);   
  });
}

Wie unter JavaScript üblich, erfolgt das Abrufen von Daten asynchron. Deswegen liefert get ein so genanntes Observable retour, das die angestoßene asynchrone Operation repräsentiert. Dieses kommt aus dem Framework RxJS, das von Angular 2 genutzt wird, und repräsentiert einen asynchronen Strom von Objekten. Bei Nutzung des HTTP-Service beschränkt sich dieser Datenstrom auf ein einziges Objekt, das die Antwort von dem Web-API repräsentiert. Das gezeigte Beispiel nutzt die Methode map, um dieses Objekt auf ein Objekt abzubilden, das den Body der Antwort repräsentiert. Da der Body als JSON-String vorliegt, ruft es dazu die Methode json auf. Subscribe abonniert im Anschluss daran den Datenstrom. Der erste übergebene Lambda-Ausdruck nimmt das Objekt, das ein Array mit den abgerufenen Flügen repräsentiert, entgegen und verstaut es im Member fluege. Der zweite Lambda-Ausdruck behandelt hingegen Fehlerfälle.

Templates erstellen

Zum Darstellen der Komponente kommt das in Listing 4 gezeigte Markup zum Einsatz. Es handelt sich dabei um herkömmliches HTML, das zusätzlich ein paar Datenbindungsausdrücke beinhaltet. Diese erkennt man unter anderem an den runden, eckigen und geschweiften Klammern. Beispiele dafür sind [(ngModel)], [disabled], (click) und {{flug.id}}. Auch wenn die Nutzung dieser Klammern anfangs ein wenig gewöhnungsbedürftig erscheint, handelt es sich bei diesen Schreibweisen um valides HTML. Darüber hinaus erhöhen sie die Nachvollziehbarkeit, zumal die verwendeten Klammern Auskunft über die Art der jeweils eingerichteten Datenbindung gibt.






<h1>Flüge suchen</h1>


<div class="form-group">
   <label>Von:</label>
   <input class="form-control" [(ngModel)]="von" name="von">
</div>


<div class="form-group">
   <label>Nach:</label>
   <input class="form-control" [(ngModel)]="nach" name="nach">
</div>


<div class="form-group">
   <input type="button" [disabled]="!von || !nach" value="Suchen!" class="btn" (click)="search()">
</div>


<table class="table table-striped">





<tr *ngFor="let flug of fluege" [class.active]="flug.id == selectedFlug?.id">





<td>{{flug.id}}</td>


<td>{{flug.abflugort}}</td>


<td>{{flug.zielort}}</td>


<td>{{flug.datum.substr(0,10) }}</td>


<td><a style="cursor:pointer" (click)="select(flug)">Auswählen</a></td>





   </tr>





</table>






Eckige Klammern binden zum Beispiel einen Ausdruck, der sich in der Regel auf den Zustand des Controllers bezieht, an das UI. Dabei handelt es sich um ein One-Way Binding, das Änderungen nur vom Controller in die View übernimmt. Hierbei ist auch von Property Binding die Rede. Der Ausdruck [disabled]=”!von || !nach″ legt beispielsweise einen Wert für das DOM-Attribut disabled fest, das dem Deaktivieren der gezeigten Schaltfläche dient, wenn von oder nach keinen Wert aufweisen

Da Angular 2 hier eine Bindung an DOM-Attribute vorsieht, benötigt das Framework keine speziellen Konstrukte für die einzelnen vom DOM gebotenen Möglichkeiten. Ferner erleichtert das auch die direkte Nutzung von frameworkübergreifenden Web-Controls, zumal diese benutzerdefinierte DOM-Erweiterungen darstellen.

Bei ngFor handelt es sich um eine so genannte Direktive, die hier über alle Flüge iteriert. Das Sternchen im Ausdruck *ngFor=”let flug of fluege” zeigt an, dass es sich bei dem aktuellen HTML-Element um ein Template handelt. Das sind HTML-Elemente, die der Browser oder das Framework zunächst nicht rendert und bei Bedarf einmal oder mehrfach in die Seite einfügt. Das Schlüsselwort let in diesem Konstrukt deklariert flug als neue Variable, die nur im aktuellen Template sichtbar ist.

Lesen Sie auch: TypeScript, Angular 2, NetBeans IDE: Ein unschlagbares Trio

Die doppelten geschweiften Klammern repräsentieren einen Platzhalter, der zur Laufzeit Werte erhält. Der Ausdruck {{flug.id}} schreibt beispielsweise die ID des aktuellen Flugs ins Mark-up. Technisch gesehen handelt es sich auch hierbei um ein One-Way Binding oder Property Binding, das einen Wert an den Inhalt des Umschließenden td-Elements bindet.

Auch der Ausdruck [class.active]=”flug.id == selectedFlug?.id” stellt eine besondere Art eines Property-Bindings dar. Dieses legt fest, dass dem Attribut class der Wert active zuzuweisen ist, wenn der hinterlegte Ausdruck wahr (true oder truthy) ist. Das Fragezeichen hinter selectedFlug ist notwendig, da selectedFlug vor dem ersten Auswählen eines Flugs null ist. Somit würde selectedFlug.id zu einem Null-Zugriff und in weiterer Folge zu einer Ausnahme führen. Während viele Template-Sprachen in solchen Fällen den gesamten Ausdruck als null auswerten, sieht das Angular 2 nicht ganz so entspannt, zumal hierdurch auch Fehler verborgen werden können. In Fällen, wo dieses Verhalten jedoch explizit gewünscht ist, greift der Entwickler zum erwähnten Fragezeichen. In Kombination mit dem darauffolgenden Punkt spricht die Community auch vom Elvis-Operator.

Runde Klammern führen zu einer Bindung an DOM-Events. So bindet der im Listing gezeigte Ausdruck (click)=”select(flug)” beispielsweise das click-Event des Links an die Methode select. Zusätzlich gibt er an, dass beim Aufruf von select der jeweils aktuelle Flug zu übergeben ist. Während Property Bindings Informationen von der Komponente an ihre View weitergeben, ist es bei Event-Bindings genau umgekehrt. Diese geben der View und den darin platzierten Komponenten die Möglichkeit, ihre Komponente zu benachrichtigen.

Als Two-Way Binding kommt in Angular 2 eine Kombination aus Property und Event-Binding zum Einsatz. Ein Beispiel dafür ist der Ausdruck [(ngModel)]=”von”. Er bindet die Eigenschaft von aus dem Controller an ein Eingabefeld und aktualisiert dieses, wenn sich von ändert. Zusätzlich reagiert er auf Benutzereingaben und schreibt die dadurch entstandenen Änderungen in die Eigenschaft von zurück. Dabei ist auch darauf zu achten, dass ngModel erzwingt, dass das jeweilge Feld einen Namen aufweist.

Um die Anwendung des Templates zur Laufzeit zu beschleunigen, führt Angular es in JavaScript-Code, den Laufzeitumgebungen gut optimieren können, über. Dieser Kompilierungsschritt kann entweder während der Ausführung oder bereits im Zuge der Entwicklung erfolgen. Ersteres nennt sich Just-in-Time-Kompilierung und bei letzterem ist spricht man von einer Ahead-of-Time-Kompilierung, welche mit dem im Lieferumfang von Angular 2 enthaltenen Template-Compiler durchzuführen ist und unter anderem zu einer Beschleunigung der Startgeschwindigkeit beiträgt. Zur Vereinfachung nimmt das hier betrachtete Beispiel in weiterer Folge mit einer Just-in-Time-Kompilierung vorlieb.

Module

Zur Strukturierung der Anwendung fasst Angular 2 die einzelnen Anwendungsbestandteile, wie Komponenten, zu Module zusammen. Jede Anwendung hat zumindest ein sogenanntes Root-Module, welches jene Komponente, die die gesamte Anwendung repräsentiert, zur Verfügung stellt. Hierbei ist auch von Root-Component die Rede. Darüber hinaus kann ein Modul andere Module mit wiederverwendbaren Code einbinden:

angular2-intro-modules

Root-Module mit Root-Component

Zur Definition eines Moduls stellt die Anwendung eine Klasse mit dem Dekorator NgModule zur Verfügung:

import {NgModule} from "@angular/core";
import {BrowserModule} from "@angular/platform-browser";
import {HttpModule} from "@angular/http";
import {FormsModule} from "@angular/forms";
import {FlugSuchenComponent} from "./flug/flug-suchen/flug-suchen.component";

@NgModule({
    imports: [
        BrowserModule, HttpModule, FormsModule
    ],
    declarations: [
	FlugSuchenComponent
    ],
    bootstrap: [
	FlugSuchenComponent
    ]
})
export class AppModule { 
}

Das betrachtete Beispiel definiert ein Modul mit dem Namen AppModule, welches drei weitere von Angular bereitgestellte Module importiert. Das BrowserModule beinhaltet die nötigen Frameworkbestandteile zur Ausführung von Angular 2 im Browser. Es referenziert auch das sogenannte CommonModul, welches allgemeine Direktiven wie ngFor anbietet. Das HttpModule beherbergt den verwendeten Http-Service und das FormsModule erlaubt das Arbeiten mit Formularen. Beispielsweise bietet es für 2-Way-Binding die Direktive ngModel an.

Unter declarations listet das Modul seine Bestandteile. Diese beschränken sich hier auf die FlugSuchenComponent. Da es sich dabei auch um die Root-Komponente handelt, und somit beim Start der Anwendung bereitzustellen ist, kommt sie auch in der Sektion bootstrap vor.

Bootstrapping in Angular 2

Zum Starten von Angular 2 wählt eine Anwendung zunächst die Plattform, in der das Framework laufen soll. Auf diese Weise legt sie beispielsweise fest, ob Angular im Browser oder serverseitig auszuführen ist. Die Plattform legt aber auch fest, ob die Templates zur Laufzeit (Just-in-Time) oder im Vorfeld (Ahead-of-Time) kompiliert werden. Zusätzlich gibt die Anwendung beim Start auch das Modul mit der gewünschten Root-Komponente bekannt. Im hier betrachteten Beispiel übernimmt die Datei boot.ts diese Aufgaben:

import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {AppModule} from "./app.module";

platformBrowserDynamic()
   .bootstrapModule(AppModule)
   .catch(err => console.error(err));

Die hier verwendete Funktion platformBrowserDynamic liefert eine Plattform-Implementierung zur Ausführung im Browser mit Just-in-Time-Kompilierung.

Damit Angular 2 die an Bootstrap übergebene Komponente in der Single-Page-Anwendung darstellt, benötigt diese ein zum Selektor der Komponente passendes Element. Im hier beschriebenen Fall handelt es sich dabei um das in Listing 1 adressierte Element flug-suchen:

<!-- index.html -->
<body>
 
 





<div class="container">
    <flug-suchen>Loading...</flug-suchen> 
  </div>





 
    […]
</body>

Debuggen von TypeScript

Auch wenn der Browser keine Unterstützung für TypeScript bietet, sondern lediglich das in Form von ECMAScript 5 vorliegende Kompilat ausführt, kann der Entwickler den geschriebenen TypeScript-Code im Browser debuggen. Möglich machen das die beim Kompilieren generierten Source-Maps, die Debugging-Informationen beinhalten. Da alle gängigen Browser Source-Maps unterstützen, kann der Entwickler in den Entwicklertools dieser Browser Break-Points im TypeScript-Code setzen und diesen Schritt für Schritt abarbeiten lassen.

Services wiederverwenden

Für wiederverwendbare Routinen bietet Angular 2 die Möglichkeit, eigene Services zu schaffen. Dabei handelt es sich im Wesentlichen um Klassen, die via Dependency Injection zur Verfügung stehen. Eine solche Klasse, welche die Datenzugriffslogik aus Listing 1 kapselt, findet sich in Listing 6. Damit sie mit dem Dependency-Injection-Mechanismus zusammenspielt, ist sie mit Injectable zu dekorieren.

Der gezeigte Konstruktor nutzt eine von TypeScript gebotene Kurzschreibweise zum Einrichten eines Parameters, der an eine gleichnamige Eigenschaft zuzuweisen ist. Diese sieht es vor, dass der Parameterdeklaration ein Access Modifier voranzustellen ist, so wie private.

import {Injectable} from '@angular/core';
import {IFlug} from '../../entities/flug';
import {Http, URLSearchParams} from '@angular/http';
import {Observable} from 'rxjs/Observable';
  
@Injectable()
export class FlugService {
    
  constructor(
    private http: Http) {
  }
    
  find(von: string, nach: string): Observable<IFlug[]> {
      
    var url = "http://www.angular.at/api/flug";
      
    var params = new URLSearchParams();
    params.set('abflugOrt', von);
    params.set('zielOrt', nach);
      
    return this.http
               .get(url, { search: params })
               .map(resp => resp.json());
      
  }
    
}

Damit Objekte dieser Klasse über Dependency Injection zur Verfügung stehen, muss eine Anwendung sie registrieren. Dazu kann sie den Service beispielsweise im Array providers eines eingebundenen Modules listen:

@NgModule({
    imports: [
        BrowserModule, HttpModule, FormsModule
    ],
    declarations: [
        FlugSuchenComponent
    ],
    providers: [
        FlugService
    ],
    bootstrap: [
        FlugSuchenComponent
    ]
})
export class AppModule { 
}

Sämtliche Services, welche sich im Array providers befinden, stehen der gesamten Anwendung zur Verfügung. Die bloße Angabe der Klasse FlugService bedeutet, dass alle Stellen, die einen FlugService in den Konstruktor injiziert bekommen möchten, auch tatsächlich eine Instanz von FlugService erhalten. Es handelt sich dabei lediglich um eine Kurzschreibweise für { provide: FlugService, useClass: FlugService}.

Wollte der Entwickler hingegen jenen Stellen, die einen FlugService benötigen, die Subklasse ExtendedFlugService zukommen lassen, würde er dies wie folgt angeben:

{ provide: FlugService, useClass: ExtendedFlugService}

In weiterer Folge kann sich die FlugSuchenComponent den FlugService anstatt des HTTP-Service injizieren lassen und bei Bedarf an diesen delegieren (Listing 8).

[…]
export class FlugSuchen { 
  
  constructor(
    private flugService: FlugService) {
  }
  […]
  search() {
    
    this.flugService
        .find(this.von, this.nach)
        .subscribe( 
      (fluege) =&amp;amp;gt; { this.fluege = fluege; },
      (err) =&amp;amp;gt; { console.debug(&amp;amp;lt;any&amp;amp;gt;err); });
    }
    […]
  }

Angular 2 Tutorial: Zusammenfassung und Ausblick

Angular 2 macht zusammen mit ECMAScript 6 bzw. TypeScript die Entwicklung von Web-Frontends beherrschbar. Der komponentenorientierte Ansatz erhöht die Wiederverwendbarkeit und Wartbarkeit, und der konsequente Einsatz von Dependency Injection gestaltet die Umsetzung testbar. Darüber hinaus unterstützt ECMAScript 6 und TypeScript Sprachkonstrukte, die frühere Versionen von JavaScript vermissen ließen. Dazu gehören Klassen, Module und Lambda-Ausdrücke.

Der nächste Teil dieses Tutorials geht auf das Thema Formulare und Validierung ein.

Verwandte Themen:

Geschrieben von
Manfred Steyer
Manfred Steyer
Manfred Steyer ist selbstständiger Trainer und Berater mit Fokus auf Angular 2. In seinem aktuellen Buch "AngularJS: Moderne Webanwendungen und Single Page Applications mit JavaScript" behandelt er die vielen Seiten des populären JavaScript-Frameworks aus der Feder von Google. Web: www.softwarearchitekt.at
Kommentare
  1. Enes2016-12-27 14:02:28

    Hallo,

    "Die komplette Implementierung des in diesem Artikel beschriebenen Beispiels findet sich . Informationen bezüglich Build und Start der Beispiele finden sich jeweils in den beigelegten Readme-Dateien."
    Das habe ich nicht ganz verstanden, wo finde ich denn das Beispiel?

  2. michi2016-12-29 00:16:24

    Google meint hier:

    https://github.com/manfredsteyer/angular-2-tutorial-rc4

  3. Martin2017-04-12 13:05:24

    Das Tutorial liest sich ganz gut.
    Schade nur, dass das Projekt sich nicht ausführen lässt, sondern ständig "neue" Fehler kommen und nach etlicher Google-Recherche wohl das Projekt einfach nicht auf dem neuesten Stand ist und daher die Nutzung nicht möglich :(

    Bekomme mittlerweile den Fehler: "Configurationhas an unkown property 'modulesDirectories' und keine Ahnung wie ich das lösen kann.. So bringt das Tutorial (zumindest mir) nix.

  4. Dagmar2017-04-21 22:16:53

    Hallo Martin,
    ich hab ein neues leeres Projekt mit "ng new Projektname" angelegt und dann alles von diesem Projekt übernommen, dann funktioniert es, man muss nur in flug.service.ts noch import 'rxjs/Rx';
    ergänzen (glaube das war alles).

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.