Das sehr beliebte, Client-seitige JavaScript Framework Angular
ist Ihnen noch kein Begriff? Sehen Sie sich unser Angular b-nova To Do List Tutorial an.
In diesem Blogpost wollen wir unsere To Do List etwas erweitern, wir erstellen eine zweite Komponente und wollen diese mit Daten “befüttern” und auf Events reagieren.
b-nova To Do List Item
Los gehts, wie Sie bereits aus dem Tutorial kennen erstellen wir mit ng
eine neue Komponente, diese soll ein einzelnes To Do Item repräsentieren.
|
|
Glücklicherweise referenziert Angular über ihr CLI Tool bereits unsere neue Komponente im app.modules.ts
File, daher können wir diese direkt einbinden.
Dies machen wir, wie auch bei anderen Komponente, über den Selektor, unser ToDo-Item soll direkt in der ngFor
Schleife der To Dos Komponente inkludiert werden.
|
|
Nun sollte unsere Komponente wie folgt aussehen, der Standardtext “to-to-item works!” sollte öfters ausgegeben werden.
Selbstverständlich ist dies aber nur die halbe Magie, nun wollen wir das HTML des To Do Items auch effektiv in der To Do Item Component haben.
Einfach verschieben? Probieren Sie es aus!
Ups, nun ist unsere To Do Liste kaputt und wir haben ein Haufen von Fehlern in der Konsole. Aber wie können wir die Daten einer Komponente zu einer anderen senden?
Input Bindings
Auch hier bietet Angular eine einfache aber mächtige Lösung, sogenannte Input Bindings. Diese erlauben uns, Daten in einer Komponente entgegenzunehmen und zu verwenden.
Schauen wir uns das HTML eines To Do Items nochmal genauer an, wir brauchen zwei Input Variablen, einmal das toDo
selbst und einmal die Variable i
welche für den Index steht.
|
|
Nun müssen wir nur noch die Daten entsprechend an die Komponente geben, über ein sogenanntes Binding
.
|
|
Hier setzen wir nun die Variable toDo
aus der ToDosComponent
auf den Input Parameter toDo
der ToDoItemComponent
.
Unsere Application sieht nun fast wieder aus wie vorher, leider gibt es weiterhin Fehler, dass die Methoden zum Abhaken und Löschen eines Items nicht gefunden werden.
Diese Funktionalität möchten wir gerne in der ToDosComponent
behalten, somit muss die ToDoItemComponent
irgendwie über eine solche Aktion des Nutzer informieren können.
Ein weiterer grosser Vorteil dieser Architektur ist, dass Daten nur einmalig geladen werden müssen.
Zusammenfassend gesagt senden wir hier Daten von der Parent zur Child Komponente.
Output Bindings
Das sogenannte Output Binding
erlaubt es uns, eigene Event mit Daten einer Komponente nach Aussen für anderen Komponenten zu versenden.
Nach einem kurzen Blick auf unsere Item Komponente fällt uns auf, dass wir zwei Event haben, einmal wurde ein Item als Erledigt markiert und einmal wurde ein Item gelöscht. Selbstverständlich könnten wir dies in zwei separaten Event abhandeln, wir möchten dies aber ’lean’ halten und nur ein Event mit einem Parameter nutzen.
Hierfür benötigen wir zwei neues Dateien, ein neues Model und ein neues Enum mit zwei vordefinierten Werten:
|
|
|
|
Nun haben wir ein “Gefäss” für unser Event, wir wissen, um was für einen Type (Complete oder Delete) und um welches To Do Item (anhand des Indexes) es sich handelt.
Ähnlich wie beim Input Bindung können wir auch hier eine Annotation nutzen:
|
|
Die Klasse EventEmitter
aus dem @angular/core
Package erlaubt es uns, custom Event zu kreieren und diese zu feuern.
Nun müssen wir unsere ToDoItemComponent noch um drei Methode erweitern, welche unseren EventEmitter aufruft und jeweilige Event ‘published’.
Zuerst implementieren wir die zwei Methoden, die direkt aus dem Template aufgerufen werden.
Anschliessend schreiben wir eine private
Methode für den emit
des Events. Da diese nach Assen nicht sichtbar ist können (und wollen) wir diese nicht vom Template direkt aufrufen.
|
|
Zu guter letzt wollen wir das Event nun in unserer ToDosComponent entgegennehmen und entsprechen darauf reagieren:
|
|
|
|
Die Methode handleToDoEvent
der ToDosComponent
wird nun immer aufgerufen, wenn in der ToDoItemComponent
ein Item erledigt oder gelöscht wird.
Zusammenfassend gesagt senden wir hier Daten von der Child zu der Parent Komponente.
Der letzte Schliff
Unsere Komponente ist nun voll funktional, leider sieht sie nicht mehr aus wie vorher.
Grund dafür ist, dass sich das Markup geändert hat und die CSS Rules in der ToDosComponent
nicht für die HTML Element aus der ToDoItemComponent
gelten.
Im ersten Schritt wollen wir das div.todo
aus der ToDosComponent
entfernen bzw. direkt durch den ToDoItem Selektor ersetzen.
|
|
Hier loopen wir nun auf einer Zeile durch unsere ToDos, geben dem Resultat die Klasse ’todo’ und nutzen Input und Output Bindings, cool oder?
Nun stylen wir unsere ToDoItemComponent
indem wir folgenden CSS Code einfügen:
|
|
Zu guter Letzt fehlt nun noch das visuelle Feedback, ob ein Item bereits abgehakt ist, hier nutzen wir ein Data Binding auf ein HTML Property, namentlich das single class binding
.
|
|
Angular erlaubt es uns, eine Boolean Expression direkt beim Definieren einer Klasse mitzugeben, so wird in das HTML Element class
der Wert done
nur geschrieben, wenn die Expression aus toDo.completed
wahr ist.
Nun sieht unsere b-nova To Do Liste wieder schön aus und ist voll funktional! :-)
Nochmal langsam
Puh, das waren nun vielen Changes und neue Feature, wir wollen nochmal kurz rekapitulieren:
- Mit
Input
nehmen wir Daten einer anderen Komponente entgegen - Mit
Output
senden wir eigene Events inklusive Daten nach Aussen
Visuell gesehen haben wir nun folgenden Aufbau:
Das komplette b-nova To Do List Projekt finden Sie auf GitHub.
Stay tuned!