© honoka/Shutterstock.com, © MaDedee/Shutterstock.com
Die Features im Überblick

Angular 9 and Friends


Angular 9 bringt Ivy mit, aber auch darüber hinaus gibt es Neuerungen am Release. Diese fallen zwar kleiner aus, bedeuten darum aber auch weniger Aufwand für die Aktualisierung. Ein Blick auf die Neuerungen jenseits der großen Features lohnt sich.

Entwickler freuen sich oft am meisten über neue Features. Und da Vorfreude die schönste Freude ist, hat das Angular-Team den neuen Ivy Renderer seit Angular 6 entwickelt, dabei jedoch stets als Preview in den Releases 6, 7 und 8 bereitgestellt. In Version 9 steht Ivy jetzt aber als neuer Default-Renderer bereit und stellt damit gleichzeitig auch die bedeutendste Änderung in Angular seit mehreren Versionen dar. Natürlich finden sich in diesem Release auch andere Änderungen, doch allgemein ist das Release primär durch Versionspflege von Abhängigkeiten und kleineren Aktualisierungen geprägt. Für typische Projekte ist daher mit einem sehr geringen Aktualisierungsaufwand zu rechnen. Zumindest, wenn man von Angular 8 kommt und seine Projekte regelmäßig gepflegt hat.

Es würde Angular nicht gerecht werden, sich lediglich auf die Kernfeatures zu fokussieren, denn gerade auch das Ökosystem rund um das eigentliche Framework macht Angular zu dem als produktiv und stabil geschätzten Werkzeug, das es heute ist. Daher betrachten wir im Folgenden auch das Angular CLI und weitere Entwicklungen aus dem Angular-Universum seit dem Release der Version 8. Als Einstieg beginnen wir mit dem Core Angular Framework.

Neuerungen in Angular

Die wichtigste Neuerung in Angular 9 ist natürlich, dass der Ivy Renderer nun zum Default wird. An dieser Stelle wollen wir uns aber mit den allgemeinen Änderungen im Angular Framework beschäftigen.

Seit dem Release von Angular 8.0.0 haben einige Neuerungen Einzug in das Framework gehalten. Einige davon sind zur Vorbereitung des 9.0.0-Release schon mit Version 8.2.0 aufgenommen worden. Dazu zählt etwa eine automatische Migration, die in Anwendungen die bereits mit Angular 4 abgekündigte Klasse Renderer gegen den seitdem empfohlenen Renderer2 austauscht. In Version 9.0.0 wird die alte Renderer-Klasse dann endgültig entfernt.

Mit Angular 8 wurde dem @ViewChildren-Decorator ein neues Flag static hinzugefügt, mit dem der Zeitpunkt bestimmt werden kann, zu dem die ViewChildren-Query aufgelöst wird. In Angular 9 wird dieses Flag nun optional. Falls es nicht mehr angegeben wird, wird die ViewChildren-Query dynamisch ausgewertet. Das bedeutet, dass das Ergebnis der Query im ngAfterViewInit() Lifecycle Hook zur Verfügung steht. Soll die Query statisch ausgewertet werden, muss das static Flag auf true gesetzt werden. Das ist allerdings nur möglich, wenn sich die aufzulösenden Elemente nicht innerhalb einer dynamischen Sub-View, also zum Beispiel innerhalb eines *ngIf, befinden.

Eine weitere Neuerung betrifft das Angular-Dependency-Injection-System. Es ist nun möglich, einen Service per providedIn: ‚platform‘ auf Plattformebene per Dependency Injection zur Verfügung zu stellen (Listing 1). Die Plattform stellt in Angular für gewöhnlich Services zur Verfügung, die speziell mit der unterliegenden Laufzeitumgebung zusammenhängen. Standardmäßig läuft eine Angular-App etwa auf der Plattform @angular/platform-browser, also auf der Browserplattform. Diese stellt zum Beispiel die BrowserPlatformLocation zur Verfügung, die intern vom Angular-Routing verwendet wird. Es ist nun möglich, mehrere Angular-Anwendungen, die die gleiche unterliegende Angular-Plattform und alle darin enthaltenen Services verwenden, auf einer Seite zu starten. Mit dem neuen providedIn: 'platform' kann ein Service also als Tree-shakable-Provider auf Plattformebene zur Verfügung gestellt werden. Weiterhin kann ein Service per providedIn: 'any' in alle NgModule Injectors aufgenommen werden. Dann erfolgt die Bereitstellung des Service immer in dem Modul, in dem er angefragt wurde. Das führt dazu, dass der Service kein App-Singleton mehr ist, sondern verschiedene, unabhängige Instanzen erzeugt werden.

Listing 1: Plattformweiter Service

@Injectable({ providedIn: 'platform' }) export class MyPlatformService { ... }

Um optimale Unterstützung beim Entwickeln von Angular-Anwendungen anbieten zu können, verlassen sich Entwicklungsumgebungen wie WebStorm und VS Code auf den Angular Language Service. Dieser ermöglicht eine gute Code Completion auch in den Angular Decorators und vor allem den Angular-Templates. Mit Angular 9 wurde der Language Service verbessert, sodass beim Hover über eine Direktive nun das Modul angezeigt werden kann, in dem sie deklariert wurde. Bei Komponenten kann der Language Service nun auf fehlerhaft angegebene templateUrl bzw. styleUrls hinweisen. Ist eine der angegebenen Dateien zum Beispiel nicht vorhanden, kann damit nun direkt die IDE einen Hinweis geben, ohne dass vorher ein Build-Prozess gestartet werden muss. In Templates bietet der Language Service nun auch Code-Completion-Unterstützung für die Angular-Pseudoelemente <ng-container>, <ng-content> und <ng-template>.

Im API von @angular/forms wurde eine Inkonsistenz bereinigt: Während es bisher möglich war, eine Zahl als formControlName anzugeben, ist das nun auch für formGroupName und formArrayName möglich.

Angular-Anwendungen können durch Nutzung des Pakets @angular/service-worker offlinefähig gemacht werden, indem zum Beispiel die Anwendungs-Bundles durch einen Service Worker lokal im Client gecacht werden. Dieser Service Worker kann auch auf dem Server neu deployte Versionen erkennen und ebenfalls clientseitig cachen. Falls eine dieser Versionen fehlerhaft ist, kann der Angular Service Worker in verschiedene Fehlerzustände übergehen. Einer dieser Zustände ist der EXISTING_CLIENTS_ONLY-Modus, der auftritt, falls neu geladene Versionen fehlerhaft sind. In diesem Modus liefert der Service Worker die gecachten Dateien nur noch an bereits verbundene Clients aus, neue Clients müssen sich die Dateien direkt aus dem Netz ziehen. Bisher war es für einen Service Worker nicht möglich, aus dem EXISTING_CLIENTS_ONLY-Modus zurück in den NORMAL-Modus zu wechseln, etwa wenn eine neue, fehlerfreie Version deployt wurde. Mit Angular 9 kann der Angular Service Worker nun in den NORMAL-Modus zurückwechseln, falls er eine fehlerfreie Version laden kann.

Breaking Changes

Wie jedes Major-Release von Angular bringt auch Version 9 einige Breaking Changes mit. Auch hier ist die Umstellung auf den Ivy-Renderer natürlich die prominenteste Änderung. Als Resultat aus dieser Umstellung ergeben sich jedoch auch viele Änderungen, die nicht unbedingt direkt ersichtlich sind, weshalb wir uns an dieser Stelle damit beschäftigen wollen. Wie oben erwähnt, kann mit Angular 9 der alte Renderer (deprecated in Angular 4) nicht mehr verwendet werden, stattdessen muss Renderer2 verwendet werden. Gleiches gilt für die zugehörigen Klassen RenderComponentType (wird ersetzt durch RendererType2) und RootRenderer (wird ersetzt durch RendererFactory2).

Mit Angular 9 ist es durch Ivy notwendig, dass alle Klassen (inklusive Sub- und Oberklassen), die Angular-Logik beinhalten, einen Angular Decorator bekommen. Bei Services ist dies der @Injectable Decorator, bei Direktiven der @Directive Decorator. Auch Oberklassen von z. B. Direktiven müssen damit nun einen @Directive Decorator bekommen. Um kennzeichnen zu können, dass es sich bei dieser Oberklasse nur um eine abstrakte Direktive handelt, ist es mit Angular 9 nun möglich, diesen @Directive Decorator auch ohne die bisher obligatorische selector Property zu verwenden. Man legt damit quasi eine abstrakte Direktive an.

Damit Code, der für den neuen Ivy Renderer geschrieben wird, zunächst abwärtskompatibel zu der bisherigen View Engine bleibt, wurden Selektor-lose Direktiven auch für die View Engine ermöglicht. Alle Projekte, die das Angular CLI verwenden, müssen sich in der Regel nicht darum kümmern, die neu notwendigen Decorators bei einem Update zu setzen: Die automatischen Migrations sorgen direkt beim Update dafür, dass Klassen, die einen Decorator benötigen, diesen auch bekommen. Listing 2 zeigt eine BaseDirective und die davon erbende SubDirective vor der Angular-9-Migration. In Listing 3 ist dasselbe Szenari...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Gewinner-Teams

Wir bieten Lizenz-Lösungen für Teams jeder Größe: Finden Sie heraus, welche Lösung am besten zu Ihnen passt.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang