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

Einzelnen Eintrag anzeigen

LinkedIn Learning kostenlos und unverbindlich testen!

Jetzt testen Alle Abonnements anzeigen
Der Anwender kann nun von der Startseite zu einer Unterseite der Single-Page-Anwendung navigieren. Allerdings ist die Unterseite noch nicht mit den entsprechenden Daten gefüllt. Das ändern Sie in diesem Video.
12:50

Transkript

In meiner Single-Page-Anwendung habe ich bereits die Möglichkeit, von der Startseite zu einer Unterseite zu navigieren. Allerdings ist diese Unterseite aktuell nicht mit den gewünschten Daten gefüllt. Wenn ich zum Beispiel hier auf die Speise "Crema de verduras" klicke, dann wäre meine Erwartungshaltung, dass hier natürlich die Gemüsesuppe steht und nicht "dish-detail works!" Damit das funktioniert muss ich noch einiges an meiner Dish-Detail-Komponente bearbeiten. Und das schauen wir uns jetzt einmal an, was hier zu tun ist. Ich wechsle dazu einmal in meine Komponente und hier sehen wir, dass diese aktuell relativ leer ist. Hier wird OnInit und Component importiert. Hier wird die Komponente annotiert und anschließend haben wir einen leeren Konstruktor. Das Erste, was wir nun benötigen, ist die ID, die in unser URL übergeben wurde, denn diese sehen Sie ja hier oben. Da steht immer die ID der Speise. Also zum Beispiel die 18 eben oder hier die 19. So, wie kommen wir an diese ID heran, um diese abrufen zu können? Dazu brauchen wir zwei Imports, nämlich einmal ActivatedRoute und paramMap. Beide befinden sich Angular/Router und die werden wir jetzt mal schnell importieren. Das Erste war, wie gesagt, ActivatedRoute und das Zweite ist ParamMap aus @angular/router. So, von diesen beiden müssen wir jetzt ActivatedRoute in unsere Komponente injizieren. Das Ganze machen wir natürlich über den Konstruktor, indem ich hier angebe private route: ActivatedRoute. So. Da wir hier OnInit bereits implementieren, kann ich diesen Initialisierungscode auch in OnInit hereinschreiben. Und zwar muss ich hier angeben this.route und jetzt greife ich zu auf die paramMap. Und auf dieser Methode muss ich jetzt die Methode switchMap aufrufen. Und switchMap sehen Sie fehlt in IntelliSense und das fehlt deswegen hier in der IntelliSense, weil ich switchMap als Operator erst importieren muss. Also wieder hoch in den Importbereich und ich importiere hier oben rxjs/add/operator/switchMap. So, jetzt kann ich hier auch, nachdem ich das Semikolon eingetragen habe, switchMap aufrufen. Und an switchMap übergebe ich jetzt params als paramMap, und das ist das paramMap, was wir hier oben importiert haben. Und das Ganze geht nach this.vegiService.getDish. Dann sagen Sie, Mensch, vegiService und getDish,das fehlt hier. Dann haben Sie recht. Was nämlich hier direkt passiert ist, ich bekomme hier in switchMap meinen Parameter übergeben und beziehungsweise meine Parameter-Map übergeben und kann das Ganze dann weiterleiten an eine weitere Methode in Form dieses Lambda-Ausdruckes. Und jetzt möchte ich hier ganz gerne meinen vegiService aufrufen. Damit ich den benutzen kann, muss ich natürlich zunächst importieren. Also, sagen wir hier oben, import {vegiService}* from ../../ vegi.service. Und an diesem möchte ich jetzt gleich gerne die Methode getDish aufrufen. Natürlich muss ich da vorher auch hingehen und den erst einmal injizieren, also private vegiService vom Typ vegiService. So, auf vegiService gibt es aktuell wie bereits gesagt keine Methode getDish, die muss ich gleich noch implementieren. Aber an getDish werde ich definitiv mal eine ID übergeben müssen, und zwar bekomme ich die aus params.get und dann den Namen meines Parameters. Das Ganze gibt mir jetzt allerdings einen String zurück. Ich möchte aber eine Zahl an getDish später übergeben. Und da gibt es jetzt einfach einen Trick. Ich mache einfach ein Plus davor und dann wird daraus schon, dank JavaScript, eine Zahl für mich. So. Als Nächstes, wenn das Ganze dann zurückgekommen ist, dann rufe ich darauf gleich die Methode subscribe auf. Bevor ich das mache, werde ich aber mal in diesen vegiService wechseln und diese Methode getDish schnell implementieren, damit wir entsprechenden IntelliSense bekommen. Der vegiService, der befindet sich im Ordner app. Und hier haben wir schon eine Methode getCategories und jetzt machen wir noch eine Methode getDish und da kommt rein eine ID als number und das gibt zurück ein Promise vom Typ Dish. Und hier sage ich return this.http.get und jetzt benutze ich hier den Backtick, weil ich ein Template-String nutzen möchte, und zwar sage ich hier `api/dishes/ und dann $ und dann in geschweiften Klammern {id}`. So. Und darauf rufe ich auf toPromise und gebe dann ein Dish zurück. as Dish. So. Dish muss ich hier noch importieren. Da beschwert sich Visual Studio aktuell drüber. So. Das habe ich jetzt auch erledigt. Hier oben haben wir also das entsprechende Import. Und jetzt kann ich nach dem Speichern wieder zurück in meine Komponente gehen und habe jetzt hier auch keine rot unterkringelten Dinge mehr, weil jetzt dieser Aufruf hier soweit in Ordnung ist. Was jetzt hier schlussendlich fehlt, nachdem ich hier eine weitere Klammer geschossen habe, ist der subscribe-Aufruf, und an den übergebe ich, dass ich ganz gerne das Dish, was ich zurückbekomme habe, auf mein aktuelles Dish setze. Auch diese Variable gibt es noch nicht, die werde ich deswegen hier oben kurz deklarieren. Also private dish vom Typ Dish. Was haben wir jetzt hier gemacht? Die Grundidee ist folgende. Meine Komponente wird initialisiert und in dem Moment, wo die Komponente initialisiert wird, nutze ich ActivatedRoute. Dort die Parameter-Map und rufe hier switchMap auf, um den entsprechenden Eintrag zu extrahieren und meinen Service aufzurufen. Sobald mein Service aufgerufen worden ist, kann ich das Ergebnis dann der Variablen Dish zuweisen, für die hier oben noch das Import-Statement benötige. Das ist schon mal der erste Schritt. Der zweite besteht darin, dass ich die Kategorien noch laden möchte, denn die Kategorien, die benötige ich, um später eine vernünftige Darstellung statt nur der Kategorie-ID zu haben. Also ich definiere ich hier oben eine Variable. Die nenne ich categories. Und die ist vom Typ Category-Array. Auch Category muss ich importieren. So. Und die befülle ich, indem ich hier im OnInit in meinen vegiService die Methode getcategories aufrufe und hier das Promise verarbeite und die zurückgelieferten Kategorien, die weise ich dann this.categories zu. So. Soweit schon mal zum Abrufen. Was hier oben jetzt noch fehlt, ist, dass ich den vegiService auch als Provider anlege. Dann werden wir jetzt Folgendes machen. Wir wechseln jetzt einmal in das Markup herein. Und jetzt werde ich hier statt "dish-detail works!" einfach schon mal hingehen und ein paar Details zu unserem dish ausgeben. Damit wir uns später auch anschauen können, ob das Ganze auch wirklich läuft. Ich wechsle dazu noch einmal zurück in den Browser, starte meine Anwendung kurz neu, indem ich hier auf die Homepage gehe. Jetzt wird das Ganze neu geladen. Ich drücke auf einen Eintrag drauf. Und hier oben steht jetzt "Ensalada de Casa". Allerdings hat er nicht komplett navigiert. Gucken wir uns auch das mal kurz an. Und das Problem, was wir hier haben, ist folgendes. Das besteht darin, er beschwert sich hier darüber, dass eine Property-ID nicht von einem undefinierten Objekt lesen kann. Und das Problem besteht darin, ich greife hier auf Eigenschaften von dish zu und dish ist am Anfang noch gar nicht komplett geladen und initialisiert. Der Trick besteht dann hierin, dass ich einfach ein ngIf herumpacke und sage, dass soll nur angezeigt werden, wenn das dish auch schon geladen ist. Andernfalls kann ich genauso wie in der menu.component hingehen und kann einen spinner implementieren. Und diesen spinner, den werde ich jetzt in der dish-detail.component oberhalb dieses p's implementieren und sage, solange es kein dish gibt, soll er sich drehen. Und anschließend kann man das Ganze dann ausgeben. So, ich habe gespeichert. Ich wechsle noch einmal zurück und starte die Seite erneut. So, und diesmal sieht es besser aus. Wir haben auch keine Fehlermeldung mehr. Wenn Sie also das gleiche Problem beim Navigieren haben, wie ich das gerade hatte, dass im Endeffekt die Komponente zwar oben so halb steht, aber der Rest fehlt, dann liegt das ganz häufig daran, dass Sie auf Eigenschaften zugegriffen haben von einem Objekt, was noch nicht initialisiert wurde, weil es noch gar nicht vom Webservice abgerufen worden ist. In meinem Code, den wir hier sehen, definiere ich erst ja mal nur das Objekt selber, weise aber noch keinen Wert zu. Der Trick dann ist, dass Sie einfach den Teil des DOMs, der auf diese Felder zugreift, dass Sie den erst einmal über ngIf ausblenden. Fassen wir aber noch einmal zusammen, welche Schritte ich benötigt habe, um die Daten abzurufen und zwar anhand des Parameters, den ich übergeben habe. Der Parameter steht wie gesagt in der URL drin. Um diesen nun zu extrahieren, habe ich Folgendes gemacht. Ich habe zwei neue Imports hinzugefügt aus @angular/router, nämlich ActivatedRoute und paramMap. Außerdem brauchte ich einen neuen Operator, nämlich den switchMap-Operator. In der Methode OnInit habe ich dann ein Objekt vom Typ ActivatedRoute genutzt, was ich vorher in den Konstruktor injiziert hatte und habe hier aufgerufen die Eigenschaft paramMap. Diese Eigenschaft paramMap ist eine Observable-Map, bedeutet, das ist eine Auflistung, die sich ändern kann. Die kann sich zum Beispiel ändern, weil die Komponente nicht neu erzeugt werden könnte, wenn ich einmal zurück und einmal wieder hin navigiere, aber mit einer anderen ID. Bedeutet also, diese Komponente, die bleibt bestehen. OnInit wird nicht neu erneut ausgeführt und dann könnte ich eventuell falsche Daten zurückliefern. Deswegen nutzen wir hier die paramMap. Die ist Observable, bedeutet, die wird auf jeden Fall neu befüllt und das bekomme ich auch hier mit. Auf der rufe ich dann switchMap auf, um anschließend den eigentlichen Wert auslesen zu können. Den übergebe ich dann an meinen Service, rufe über den die Daten ab und dann kann ich schlussendlich in einem subscribe dann die Daten zuweisen. Ich habe hier ein subscribe statt ein when benutzt, weil ich an dieser Stelle hier die Daten eventuell aktualisiert bekomme. Und bei einem Observable müssen wir uns subscribe über einem Promise können wir das Ganze über when beenden.

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
Erscheinungsdatum:25.09.2017

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!