Am 14. September 2017 haben wir eine überarbeitete Fassung unserer Datenschutzrichtlinie veröffentlicht. Wenn Sie video2brain.com weiterhin nutzen, erklären Sie sich mit diesem überarbeiteten Dokument einverstanden. Bitte lesen Sie es deshalb sorgfältig durch.

SPA mit ASP.NET Core und Angular

Einträge anlegen

LinkedIn Learning kostenlos und unverbindlich testen!

Jetzt testen Alle Abonnements anzeigen
Zum Schluss soll der Anwender der Single-Page-App die Möglichkeit erhalten, auch selbst neue Daten anzulegen. Diese Möglichkeit programmieren Sie in diesem Film.
15:23

Transkript

In meiner Anwendung kann ich bereits Daten anzeigen, Daten editieren und ich kann Daten auch wieder löschen. Nun ist es an der Zeit, auch die Funktionalität hinzuzufügen, um Daten anzulegen. Dazu gehe ich wie folgt vor: Im ersten Schritt öffne ich meinen Service, der für mich auf der Client-Seite die Kommunikation zum Backend übernimmt. Hier habe ich bereits eine Methode save und die ruft aktuell über http.put meine API auf. Im Fall einer Neuanlage möchte ich allerdings mit einem http.post arbeiten. Ich könnte nun entweder eine neue Methode anlegen oder aber ich arbeite hier mit einer Fallunterscheidung. Ich kann nämlich den Fall, ob ich anlegen oder updaten möchte, sehr gut unterscheiden. Immer dann, wenn die ID meines Dish-Eintrags null ist, dann möchte ich den Datensatz neu anlegen, ansonsten möchte ich den Datensatz abändern. Bedeutet also, ich werde hier einfach mit einem if arbeiten und sage hier if(dish.id), sprich, wenn die ID gesetzt ist, dann möchte ich gerne den bisherigen Code ausführen, nämlich den Code, der den Datensatz aktualisiert. Und im anderen Fall, wenn ich also keine ID habe, dann möchte ich ganz gerne meine API aufrufen, und zwar mit dem Verb post. Das Ganze geht dann auf api/dishes und ich übergebe mein Dish. Außerdem muss ich wieder das Ganze in einen Promise überführen. Dazu rufe ich toPromise auf und anschließend verarbeite ich noch die Antwort, indem ich das JSON des Bodys parse und das in einen Dish-Eintrag caste. So, das ist also der erste Weg. Ich kann jetzt schon einmal Daten theoretisch speichern. Was noch fehlt, ist natürlich die Oberfläche. Wie lege ich die an? Ich wechsle ganz einfach in die Eingabeaufforderung -- meinen bestehenden Buildprozess, den breche ich einmal gerade ab. Und nun lasse ich mir eine neue Komponente generieren, nämlich ng, dann g für generate. Ich hätte gerne eine component und die soll in dem Unterordner dishes liegen und heißt add-dish. So, das ging relativ flott. Hier rechts sehe ich auch bereits meine neue Komponente. Und von der Grundidee her, ist diese neue Komponente ganz ähnlich wie die, die wir davor schon für das Editieren hatten, also die Details-Komponente. So, ich starte hier schon mal schnell wieder den Buildprozess im Hintergrund. Und jetzt werde ich meine Komponente mit Leben befüllen. Zum einen schaut es so aus, dass das Markup relativ gleich ist. Ich kann mir also das ganze Markup meiner aktuellen Detailseite, in der ich ja schon Datensätze bearbeiten kann, kopieren und füge das hier wieder ein -- mit dem Unterschied, dass ich keinen Löschen-Button beim Anlegen brauche. Ansonsten habe ich hier ein Formular. Dieses Formular, das zeigt aktuell eine Ladeanimation an. Solange ich noch keinen Dish und keine Kategorien geladen habe, auch da muss ich natürlich das Ganze auf die Kategorien nur noch einschränken. Mal abgesehen davon, habe ich hier einige Input-Felder für Name, Beschreibung und so weiter. Nachdem ich das Markup jetzt editiert habe, werde ich als Nächstes teilweise den Code der Komponentenklasse übernehmen. Was wir hier benötigen, ist zum einen der Router, zum anderen werde ich den VegiService benötigen und darüber hinaus mit Sicherheit auch noch Category. Bedeutet, ich kopiere mir hier schon mal Category, VegiService bis hier oben hin zum Router. Das hole ich alles in die Imports hinein und wechsle jetzt hier in meine Komponente. Und hier schaut es so aus: Ich brauche hier nur den Router. Ich brauche dieses Import an der Stelle nicht. Ich werde aber sicherlich den VegiService brauchen. Ich werde auf jeden Fall auch Category brauchen und Dish vermutlich auch. Aber ich wechsle erst einmal zurück. Und was hier die Constructor Injection angeht, werde ich mir den VegiService und auch den Router kopieren aus meiner bestehenden Datei, heißt also, hier im Constructor werden mir sowohl der Service als auch der Router importiert. Dann werde ich mir aus meiner bestehenden Komponente auch das Array von Categories und auch das Feld für einen Eintrag, nämlich für einen Dish, kopieren. Mit dem kleinen Unterschied, dass ich hier direkt ein neues Dish anlege, also, ich werde hier einen neuen Eintrag erzeugen. Denn diesen möchte ich gleich editieren und dann auch binden. So, wenn wir jetzt einmal weiterschauen, dann benötige ich hier noch die Methode save. Und die Methode save, die ruft am VegiService die Methode saveDish auf, übergibt das aktuelle Dish und dann wird zurück zur Startseite navigiert. Also, auch einmal hier zurück in meine Komponente und die Methode save kopieren. Außerdem brauche ich auch das Abrufen der Kategorien, damit ich die Kategorie auswählen kann. Hier habe ich also den Aufruf des Category-Services, der dann später die Kategorien meinem Feld hier oben zuweist. Damit ist meine Komponente erst einmal so weit fertig und fast schon einsatzbereit. Was nun noch fehlt, ist die Definition einer Route. Und zwar möchte ich ganz gerne im App Routing Module diese neue Komponente, die ich gerade geschrieben habe, importieren. Das ist die AddDishComponent und die importiere ich aus dishes/add-dish/add-dish.component. Zu dieser Komponente werde ich jetzt eine Route definieren und diese Route, die hat folgenden Pfad. Die hat den Pfad dish/add und die Komponente, zu der wir navigieren wollen, das ist die AddDishComponent. So eine neue Komponente, die muss ich auch immer in der app.module.ts importieren, also an dieser Stelle hier. Und das hat für mich bereits der Generator erledigt, heißt, das muss ich gar nicht mehr selber machen, diese Komponente zu importieren. Was jetzt eigentlich nur noch fehlt, ist ein Link, der mich zu dieser neuen Seite führt. Und da möchte ich gerne Folgendes machen. In meiner Menüseite hätte ich gerne unten rechts so ein kleines Plus-Icon, so wie wir das auch von anderen Apps im Material Design kennen. Und dazu öffne ich meine Menükomponente und werde hier unten, unter das md-list, nun ein span anfügen und das bekommt die Klasse add-button. Diese Klasse, die muss ich gleich noch anlegen. In diesem span habe ich einen Button und das ist so ein runder Button. Das mache ich über md-fab. Und ich möchte hier das Click-Event registrieren, und zwar möchte ich hier die Methode addDish aufrufen. Diese Funktion, die muss ich gleich noch an meiner Komponente entsprechend anlegen. Außerdem möchte ich gerne ein Icon benutzen, nämlich ein md-icon, also ein Material Design-Icon, und zwar das Icon add. Eine Übersicht, welche Icons es gibt, die finden Sie auf der Angular Material-Dokumentationsseite und das sind mittlerweile mehrere Hundert, die Sie hier nutzen können. So, was jetzt noch fehlt, ist diese Klasse add-button, also wechsle ich in meine menu.component.css und lege die an. Und was macht diese Klasse add-button? Deren Zweck ist es, meinen Knopf rechts unten zu positionieren. Dazu sage ich einfach, dass die Position vom Typ fixed ist. Bedeutet, beim Scrollen verändert die sich nicht, sondern bleibt immer an der gleichen Stelle stehen, und zwar vom unteren rechten Rand jeweils 20 Pixel entfernt. Zu guter Letzt werde ich noch die Navigation einbauen. Dazu wechsle ich in meine menu.component und in der menu.component werde ich jetzt die Methode addDish hinterlegen, die ich hier an dieser Stelle aufrufe. Also, addDish -- ich übergebe nichts -- hier vom Typ void, und die macht nichts anderes, außer den Router zu benutzen. Und dann navigiert die zu der Route, die wir eben definiert haben. Und das war /dish/add. So, schauen wir einmal hier herüber in den Bildprozess. Das sieht alles so weit erst mal hier unten gut aus, heißt also, ich werde jetzt einmal in den Browser gehen und lade die Seite kurz neu. Und hier unten ist unser Add-Button, den wir hinzugefügt haben. Den werde ich jetzt einmal anklicken. Und jetzt lande ich auf der neuen Seite, aber hier gibt es noch einen kleinen Fehler. Schauen wir mal gemeinsam, was das sein könnte, indem ich in die Entwicklertools hereinschaue. Und hier zeigt er mir einen Fehler. Und dieser Fehler, den wir hier sehen, der sagt, es gibt keinen Provider für VegiService. Das darf ich natürlich nicht vergessen und das ist auch ein gar nicht so seltener Fehler: Jedes Mal, wenn Sie also einen Service benutzen, dann müssen Sie diesen als Provider in Ihrer Komponente auch angeben, heißt also, hier in meiner addDish-Komponente muss ich einen Eintrag providers hinterlegen und dann kann ich hier den VegiService angeben. Eine Alternative dazu wäre übrigens, dass ich hingehe und diesen VegiService -- da ich den ja tatsächlich in fast allen Komponenten bisher gebraucht habe --, den könnte ich also nicht nur hier angeben, sondern den hätte ich auch in der AppModule angeben können, hier im unteren Bereich. Wichtig ist nur, dass ich ihn registriere, entweder in jeder Komponente, in der er benötigt wird, oder im AppModule. Dann versuchen wir unser Glück noch einmal. Wir wechseln also zurück auf die Startseite, ich drücke den Plus-Button und bekomme ich etwas, was so ähnlich aussieht wie ein Formular, nur nicht ganz so schön. Und das liegt daran, dass die CSS-Definitionen aktuell noch fehlen, die ich nämlich hier in der dish-detail.component angelegt hatte. Auch die werde ich jetzt hier einmal schnell herüberkopieren. Und ein weiteres Problem, das zeige ich Ihnen auch schnell. Und da habe ich Sie extra reinlaufen lassen -- beziehungsweise uns --, weil das auch etwas ist, was sehr viel Kopfzerbrechen erst mal verursachen kann. Wenn wir in die Browser-Tools reinschauen, dann sehen wir hier ein paar Fehler; das sind insgesamt 34 Stück. Und zwar kommt hier die Meldung: "Cannot read property 'length' of undefined", und zwar aus der AddDishComponent.html in der Zeile 5. Was kann das denn bedeuten? Wenn wir mal in die AddDishComponent.html hereinschauen, dann sehen wir, dass wir hier in der Zeile 5 diesen Hinweis haben, wie viele Zeichen bereits eingegeben worden sind. Und dazu greife ich auf mein Model, also auf das Objekt Dish zu und dann auf die Eigenschaft name, und ab name dann auf length. Nun ist name allerdings null und ich rufe auf null length auf und das gibt jetzt diese Fehlermeldung. Was können wir dagegen machen? Das Einfachste ist, ich gehe einfach zur Definition meiner Klasse und bei den String-Properties, die die also standardmäßig null sind, denen gebe ich einfach einen initialen Wert von einem leeren String. Das macht jetzt weiter nichts kaputt, hilft uns aber ungemein, denn wenn ich nun hingehe und meine Anwendung noch einmal neu lade und auf den Hinzufügen-Button klicke, dann sieht das hier schon viel besser aus. So, dann fügen wir auch einmal eine Speise hinzu, zum Beispiel den "Ensalada Fantasia" mit: "Allem was in der Küche übrig ist". Und der kostet jetzt nicht ganz so viel, der kostet meinetwegen nur 1,99. Und der befindet sich in der Kategorie Ensaladas, also Salate. So, ich drücke auf Speichern. Ich wurde automatisch auf die Startseite zurückgeleitet und hier sehen wir jetzt unseren neuen Salat. Der hat also hier die ID 1002 erhalten. Die ist aus der Datenbank generiert worden und aus der API zurückgekommen. Und auch unsere Beschreibung sowie der Preis, den wir eingegeben haben, das ist alles vorhanden. Das Hinzufügen eines neuen Datensatzes, das war jetzt also gar nicht weiter schwierig. Die komplexen Punkte waren -- abgesehen davon, dass ich die Komponente anlegen musste --, dass ich darauf achte, dass ich, wenn ich einen leeren Datensatz habe und Datenbindung auf dieses Objekt durchführe, dass ich dann Eigenschaften, bei denen ich auf Kind-Eigenschaften zugreife, also name.length zum Beispiel, dass ich die in meiner Ursprungsklasse initialisiere. Ansonsten bekomme ich eine Fehlermeldung. Ansonsten war es noch ganz interessant, mal diesen Plus-Button zu sehen. Man kennt das zum Beispiel von Android oder eben auch von anderen Anwendungen, Webanwendungen zum Beispiel in Material Design. Der ist immer rechts unten. Und die Grundidee, wie Sie den rechts unten hinbekommen, ist, dass Sie einfach ein wenig CSS dazu benutzen. Und zwar setzen Sie die Position auf fixed und den rechten und den unteren Rand auf 20 Pixel.

SPA mit ASP.NET Core und Angular

Lernen Sie die Bestandteile von modernen Webanwendungen kennen und nutzen.

5 Std. 21 min (36 Videos)
Derzeit sind keine Feedbacks vorhanden...
 
Hersteller:
Exklusiv für Abo-Kunden
Ihr(e) Trainer:
Erscheinungsdatum:25.09.2017
Laufzeit:5 Std. 21 min (36 Videos)

Dieser Online-Kurs ist als Download und als Streaming-Video verfügbar. Die gute Nachricht: Sie müssen sich nicht entscheiden - sobald Sie das Training erwerben, erhalten Sie Zugang zu beiden Optionen!

Der Download ermöglicht Ihnen die Offline-Nutzung des Trainings und bietet die Vorteile einer benutzerfreundlichen Abspielumgebung. Wenn Sie an verschiedenen Computern arbeiten, oder nicht den ganzen Kurs auf einmal herunterladen möchten, loggen Sie sich auf dieser Seite ein, um alle Videos des Trainings als Streaming-Video anzusehen.

Wir hoffen, dass Sie viel Freude und Erfolg mit diesem Video-Training haben werden. Falls Sie irgendwelche Fragen haben, zögern Sie nicht uns zu kontaktieren!