Angular 2+

Blog – Technik und Methoden
Verfasst von Senay Uzuner am 3. Mai 2018

Einführung

In der heutigen Softwarewelt hat Angular 2 zunehmende Popularität. Um mich zu verbessern und in die Zukunft zu investieren, habe ich mich entschieden Angular zu lernen. Ich werde mit euch teilen, was ich bis jetzt gelernt habe.

Angular JS erschien im Jahre 2009 als JavaScript Webframework zur Erstellung von Single-Page-Anwendungen nach einem Model-View-View-Model (MVVM) Muster, welches ab 2012 zum großen Hype wurde. Es ermöglicht eine schnellere und einfachere Umsetzung von Web-Anwendungen. Techniken wie MVVM, Two-Way-Databinding und Dependency Injection ermöglichen eine bessere Testbarkeit und Wartbarkeit. Trotz der vielen Vorteile weist das Framework auch einige Nachteile auf: Erheblich komplexe Stellen im Kern sowie schlechte Skalierbarkeit und Wartbarkeit durch Nutzung einer nicht statisch typisierten Sprache.

Aus diesem Grund hat das Angular-Team sich entschlossen die Angular JS 2.0 Version mit den gewonnenen Erfahrungen komplett neu zu entwickeln. Als größte Neuerung ist die Verwendung der Sprache TypeScript zu nennen, welche JavaScript ablöst.

TypeScript ist eine von Microsoft entwickelte Sprache, die Klassen, Interfaces, Vererbung, Module, anonyme Funktionen, Generics und statische Typisierung aufweist. Dieser modernen Sprachkonstrukte ermöglichen uns, Projekte mit einer sehr guten Struktur aufzubauen und diese einfach zu erweitern, um damit auf die wachsenden Anforderungen unserer Anwendung zu reagieren. Ein sehr wichtiger Punkt ist die Verwendbarkeit von Entwicklungswerkzeugen zur Durchführung von Code-Refakturierungen. Ohne statische Typisierung ist das unter JavaScript ein sehr schwieriges Thema.

Eine weitere Neuerung in Angular 2 ist die RxJS Bibliothek für asynchrone Programmierung. RxJS ist eine Kombination von Observer, Operator Pattern und funktionaler Programmierung, welches für asynchrone Programmierung geeignet ist. Somit setzt Angular 2 nicht mehr auf Promises, sondern auf Observables.

Unterschiede zwischen Promises und Observables

Promises und Observables sind eine Abstraktion von asynchronen Aufrufen. Promises liefern uns den Zeitpunkt des Endes eines asynchronen Aufrufs oder dessen Fehlschlag. Mit einem Promise kann nur ein Wert überliefert werden. An ein Promise wird ein Callback übergeben, der aufgerufen wird, wenn der asynchrone Aufruf beendet ist. Ein weiterer Callback kann für den Fall eines Fehlers übergeben werden. Ein Promise folgt dem Muster promise.then(callBackSuccess).catch(callBackError).

Zusammengefasst :

  • Hält nur einen zukünftigen Wert
  • Kann nicht abgebrochen werden
  • Einmalige Ausführung.

Observables hingegen können mehrere Werte liefern und sind auch abbrechbar. Ein Observable kann wie ein Datenstrom betrachtet werden. Eine unbekannte Menge an Daten kann in der Zukunft bereit stehen. Um Daten von einem Observable zu verarbeiten, muss eine Anmeldung .subscribe() erfolgen. Sollen keine Daten mehr verarbeitet werden, kann eine Abmeldung durch .unsubscribe() erfolgen. Observables können noch viel mehr, z.B. können Anfragen wiederholt werden, Daten können transformiert werden, der Datenstrom kann gefiltert werden.

Observable.retry(2).repeat(3).map(res => res.json()).filter(res => res.length > 0).map(res => res[0].enabled == true).subscribe(id => console.log(‘id added ‘ + id), error => console.log(error.message));

Zusammengefasst :

  • Solange Änderungen vorhanden sind, werden Werte übermittelt
  • Durch das Abmelden kann der Prozess abgebrochen werden
  • Von der Anmeldung bis Abmeldung ist ein Observable aktiv und liefert Werte bei Veränderungen
  • Wiederholbar, falls ein Fehler auftaucht
  • Verschiedene Operationen verfügbar auf den Datenstrom wie filtern oder transformieren.

Architektur von Angular

Die Architektur einer Angular 2 Applikation besteht aus folgenden Elementen:

  • Module
  • Komponenten
  • Direktiven
  • Pipes
  • Datenbindung
  • Dependency Injection
  • Services
  • Router
  • Template
  • Metadata

Angular Architektur

Template:

Ein Template ist die Vorlage für die Darstellung der Seite. Durch spezielle Blöcke oder Anweisungen werden Inhalte eingebunden, auf Ereignisse reagiert und Kontrollstrukturen eingebunden. Ein simples Beispiel für ein Template:

Komponente:

Eine Komponente ist eine Controller-Klasse mit einem Template, die Teile der Logik einer Seite realisiert, z.B:

Databinding:

Durch DataBinding kommuniziert die Komponente mit dem Template. Dadurch können vom Benutzer ausgelöste Ereignisse oder Eingaben von der Komponente verarbeitet werden. Die von der Komponente berechneten Werte können im Template dargestellt werden.

Modul:

Ein Modul ist ein Art von Container für Komponenten, Direktiven, Pipes und Services, die eine bestimmte gemeinsame Aufgabe erfüllen müssen. Somit werden bestimmte Funktionalitäten für eine Wiederverwendung gekapselt.

Dependency Injection:

In Angular werden die Abhängigkeiten mit Dependency Injection aufgelöst. Komponenten, Direktiven, Services, Module sind Container Managed. Abhängigkeiten werden definiert und während der Laufzeit injiziert. Für die Entkoppelung der einzelnen Bestandteile und Testbarkeit hat die Dependency Injection sehr große Bedeutung.

Direktive:

Direktiven sind Komponente ohne Template, die in sich gekapselt sind. Sie verändern entweder die Struktur des Dokuments, das Aussehen oder das Verhalten von Elementen.

Deshalb gibt es drei Arten von Direktiven:

  • Komponent-Direktive: Diese Komponenten vereinen Controller und View, um wiederverwendbare Bausteine zu erhalten.
  • Strukturale-Direktive: Das sind Direktiven für die Gestaltung des Programmflusses der Templates wie *ngFor oder *nglf.
  • Attribute-Direktive: Diese Art der Direktive ermöglicht es, DOM Elemente mit zusätzlicher Funktionalität auszustatten (ngStyle,ngClass).

Metadaten:

Metadaten sind Dekoratoren für Klassen, um deren Eigenschaften im System zu definieren. Sie können mit Annotationen in Java verglichen werden. Soll eine Klasse als Komponente deklariert werden, werden die Metadaten wie folgt angegeben.

Router:

Der Angular Router übernimmt die Navigation innerhalb der Webseite. Dabei kann der Router Parameter von URLs erkennen und weitergeben. Jedes Angular-Modul kann seine eigene Navigation zu den untergeordenete Seiten verwalten. Der Router kann Seiten bei Bedarf (lazy) oder auch beim Start der Anwendung (eager) laden. Er lädt die Komponenten einer Seite in die dazugehörigen Platzhalter. Als Beispiel: Bei einer Seite mit Kopf, Menu, Inhalt und Fusszeile müssen mindestens 4 Komponenten in die dafür definierte Bereiche geladen werden. Diese Aufgabe übernimmt der Router.

Pipe:

Pipes sind Transformatoren, die Daten entgegennehmen und transformiert wieder ausgeben. Dabei wird der Input und der Name durch ein Pipe | getrennt.

Beispielsweise kann ein Pipe zur Übersetzung verwendet werden. So könnte z.B. ‘hallo’ | translate aus einer Übersetzungstabelle ‘hello’ liefern.

Service:

Services sind ähnlich wie in anderen Programmiersprachen eine Ansammlung von Funktionalitäten, die ein Themengebiet abdecken. So kann die Funktionalität einer Komponente in einem Service abstrahiert werden. Services werden durch Dependency Injection eingebunden. Sie können zwischen Komponenten ausgetauscht werden, um eine gemeinsame Funktionalität zu gewährleisten. Services können auch ohne Komponenten existieren, um bestimmte übergreifende Funktionalitäten zu bieten. Beispielsweise könnte ein NotificationService dazu dienen, um Nachrichten im System zu versenden und zu empfangen, oder ein LogService, um Nachrichten zu loggen.


Es gibt inzwischen eine neue Angular Version. Angular 5 wurde vor kurzem veröffentlicht. Es gibt etliche Verbesserungen, neue Features, Performanceverbesserungen usw., aber es hat sich an den grundsätzlichen Konzepten nichts geändert. Angular bleibt weiterhin abwärtskompatibel.

Ich habe versucht, mit diesem Artikel einen kurzen Überblick über Angular zu geben. Ich hoffe, ich konnte dadurch das Interesse an Angular wecken.