Radikale Reaktivität in Angular Teil 1
Radikale Reaktivität in Angular Teil 1
Einführung in RxJS
In diesem Artikel werde ich versuchen zu zeigen, wie typischer Anfängercode aussieht, welche Probleme er verursacht und wie man sie beheben kann. Die Demo-App zeigt sogar, welches Zustandsdesign für reaktiv eintreffende Updates optimal ist, um den geringsten "Wartungsaufwand" zu haben.
Sie finden alle Beispiele der Demo-App auf meinem GitHub. Klonen Sie den Code, führen Sie `npm install` und `npm start` aus und beginnen Sie zu experimentieren.
Demo-Anwendung
Ich habe eine Demo-Applikation geschrieben, die es einem imaginären Agenten erlaubt, Kunden und Autos zu verwalten und den Kunden Autos zuzuweisen. Stellen Sie sich das als die Benutzeroberfläche eines Angestellten in einer etwas seltsamen Autovermietung vor.
Die Benutzeroberfläche der Demo-App
Diese Demo-Anwendung besteht aus mehreren verschiedenen Phasen, die in Git-Branches organisiert sind und alle die gleiche Funktionalität bieten, aber mit unterschiedlicher Codequalität implementiert sind.
Ich empfehle Ihnen dringend, sich das Repository anzuschauen und den Code dort zu studieren. Hunderte von Codezeilen hier einzufügen, wird nicht hilfreich sein, daher werde ich nur die wichtigsten Punkte erläutern.
So funktionieren die Branches des Repositorys:
- naive-implementation
versucht, typischen Anfängercode zu reproduzieren. Versuchen Sie, die Probleme zu finden, die dieser Code hat. Fragen, die Sie sich stellen können, sind "wie funktionieren Observables, und was ist das Besondere an Observables, die vom Angular http-Client zurückgegeben werden?", "warum brauchen wir Services in Angular?" und "warum benutzen wir Typescript?".
- highlight-problems
verwendet den selben Code, hat aber lange Kommentare, die erklären, warum bestimmte Teile des Codes problematisch sind. Es lenkt Ihre Aufmerksamkeit auf typische Anti-Patterns, die es sehr einfach machen, den Code eines Anfängers von dem eines Experten zu unterscheiden.
- refactor-component
behandelt diese Probleme unter der Annahme, dass Sie nur die Komponente ändern können. Dies ist eine typische Situation in großen Projekten, in denen man nicht einfach Dinge im Servicelayer ändern kann. Zugegeben, dieser Code ist sehr kompliziert, aber er zeigt gut, wie RxJS-Code durch Komposition an Struktur gewinnt, und behandelt bereits einige Edge-Cases, bei denen wir fortgeschrittene Tricks brauchen, damit unser Event-Netzwerk reibungslos funktioniert.
- move-to-service
beginnt, wie professioneller Code auszusehen, indem die gesamte Logik, die sich mit der Zustandsverwaltung befasst, in den Servicelayer verlagert wird, wo sie wiederverwendet werden kann. Unsere Komponentenklasse schrumpft beträchtlich, da sie jetzt nur noch die Komplexität verwalten muss, die der Komponente selbst innewohnt.
- reactive-flux-cache
geht davon aus, dass unser Dienst über einen Kanal für Echtzeit-Updates aus dem Backend verfügt, so dass der Zustand immer auf dem neuesten Stand gehalten wird. Dies kann zum Beispiel mit Hilfe eines Websockets implementiert werden. In dieser Anwendung wird das Backend natürlich gemockt, so dass es nicht notwendig ist, dies tatsächlich zu implementieren. Wenn wir jedoch davon ausgehen, dass wir eine Flux-Architektur bis hin zum Backend haben, können wir die Art und Weise, wie der Zustand verwaltet wird und die Kommunikation stattfindet, grundlegend ändern. Auch die Änderung der "Backend-API", die ihre Daten in einem einfacheren Format liefert, ermöglicht es uns, die Menge an Logik zu reduzieren, die erforderlich ist, um Datenänderungen in den Zustand zu integrieren.
- Die letzte wichtige Hürde wird mit component-borders
überwunden: Wie kann man Daten zwischen Eltern- und Kindkomponente reaktiv weitergeben? Ich schlage ein allgemeines Muster vor, das auch für andere Fälle funktioniert, wie @ViewChild()
. Die Verwendung dieser Technik bietet ein wiederverwendbares Pattern für die Datenübergabe in der reaktiven Welt und ermöglicht es Ihnen, die Anzahl der Lifecycle-Hooks, die Ihre Komponenten benötigen, drastisch zu reduzieren.
In den nächsten Beiträgen werden wir einige der Probleme besprechen, die wir im Demoprojekt gefunden haben, und einige, die darüber hinausgehen. Natürlich mit Vorschlägen, wie man sie verbessern kann. Sie konzentrieren sich auf
- Composition
- Fehlerbehandlung
- Vermeidung von Memory-Leaks
- Vermeidung von Seiteneffekten
- Austausch von Daten zwischen Komponenten
Über den Autor
Matthias erreicht gerne mit wenig Aufwand große Ziele und löst komplexe Probleme nur einmal, aber korrekt. Als Senior Web Entwickler lebt er diese Philosphie im Umfeld von Angular, VueJS, Deployment Pipelines, UI-Libraries, State-Management Systemen, Typescript-Backends und was sonst eben gerade seine Aufmerksamkeit benötigt. Gerne lässt er sich dabei von Kollegen inspirieren und übernimmt Konzepte von verschiedenen Technologien, wie RxJS, NixOS, oder Rust. Auch gibt er dieses Wissen stets gerne weiter, um die Entwicklung und das Fortbestehen performanter, glücklicher Entwicklerteams zu fördern.