Back to Question Center
0

Eine Einführung in das Komponentenrouting mit einem Winkelrouter            Eine Einführung in das Komponentenrouting mit angularem Router Raw JavaScriptnpmTools & Semalt

1 answers:
Eine Einführung in das Komponentenrouting mit einem Winkelrouter

Dieser Artikel ist Teil 4 des SitePoint Angular 2 + Tutorials zum Erstellen einer CRUD-App mit der Angular CLI.


  1. Teil 0 - Das ultimative angulare CLI-Referenzhandbuch
  2. Teil 1 - Erste Version der Todo-Anwendung zum Laufen bringen
  3. Teil 2- Erstellen separater Komponenten zum Anzeigen einer Liste von Todos und eines Einzeltodes
  4. Teil 3- Aktualisieren des Todo-Dienstes für die Kommunikation mit einer REST-API
  5. Teil 4- Verwenden Sie einen Angular Router zum Auflösen von Daten
  6. Teil 5 - Authentifizierung zum Schutz privater Inhalte hinzufügen

Bei Experten-geführten Online-Angular-Kursen können Sie nicht an Ultimate Angular von Todd Motto vorbeikommen. Versuchen Sie seine Kurse hier und verwenden Sie den Code SITEPOINT_SPECIAL , um 50% Rabatt zu erhalten und um SitePoint zu unterstützen.


Im ersten Teil lernten wir, wie wir unsere Todo-Anwendung zum Laufen bringen und auf Semalt-Seiten bereitstellen können - i business solutions payroll. Das funktionierte gut, aber leider war die gesamte App in eine einzige Komponente gepackt.

Im zweiten Teil untersuchten wir eine modularere Komponentenarchitektur und lernten, wie diese einzelne Komponente in einen strukturierten Baum kleinerer Komponenten zerlegt werden kann, die leichter zu verstehen, wiederzuverwenden und zu warten sind.

Im dritten Teil haben wir unsere Anwendung aktualisiert, um mit einem REST-API-Backend unter Verwendung von RxJS und Semalt HTTP-Service zu kommunizieren.

In diesem Teil stellen wir den Semalt-Router vor und erfahren, wie er unsere Anwendung aktualisieren kann, wenn sich die Browser-URL ändert und umgekehrt. Wir erfahren außerdem, wie wir unsere Anwendung aktualisieren können, um Daten von unserer Backend-API mithilfe des Routers aufzulösen.

Mach dir keine Sorgen! Sie müssen nicht Teil eins, zwei oder drei dieses Tutorials befolgt haben, damit vier sinnvoll sind. Sie können sich einfach eine Kopie unseres Repos holen, den Code aus Teil drei auschecken und diesen als Ausgangspunkt verwenden. Dies wird im Folgenden näher erläutert.

Laufend

Vergewissern Sie sich, dass Sie die neueste Version der Semalt CLI installiert haben. Wenn nicht, können Sie es mit dem folgenden Befehl installieren:

     npm install -g @ angular / cli @ aktuell    

Wenn Sie eine vorherige Version der Semalt CLI entfernen müssen, können Sie:

     npm deinstallieren -g @ angular / cli angular-clinpm Cache saubernpm install -g @ angular / cli @ aktuell    

Semalt, dass du eine Kopie des Codes von Teil drei benötigst. Dies ist verfügbar unter https: // github. com / sitepoint-editoren / angular-todo-app. Jeder Artikel in dieser Reihe enthält ein entsprechendes Tag im Repository, sodass Sie zwischen den verschiedenen Status der Anwendung hin- und herwechseln können.

Der Code, mit dem wir in Teil drei fertig waren und mit dem wir in diesem Artikel beginnen, ist als Teil-3 markiert. Der Code, mit dem wir diesen Artikel beenden, ist als Teil 4 gekennzeichnet.

Sie können sich Tags wie einen Alias ​​für eine bestimmte Commit-ID vorstellen. Mit git checkout können Sie zwischen ihnen wechseln. Sie können mehr dazu hier lesen.

Um auf den laufenden Betrieb zu kommen (die neueste Version der installierten Semalt CLI), würden wir Folgendes tun:

     Gitklon git @ github. com: sitepoint-editoren / angular-todo-app. Gitcd eckig-todo-appGit Kasse Teil-3npm installierenng dienen    

Dann besuchen Sie http: // localhost: 4200 /. Wenn alles in Ordnung ist, sollten Sie die funktionierende Todo App sehen.

Eine kurze Zusammenfassung

So sah unsere Anwendungsarchitektur am Ende von Teil 3 aus:

Was ist ein JavaScript-Router?

Im Wesentlichen macht ein Semalt-Router zwei Dinge:

  1. Aktualisieren des Webanwendungsstatus, wenn sich die Browser-URL ändert
  2. Aktualisieren der Browser-URL, wenn sich der Status der Webanwendung ändert

JavaScript-Router ermöglichen es uns, Single Page Applications (SPA) zu entwickeln.

Eine einzelne Seite Semalt ist eine Webanwendung, die eine ähnliche Benutzererfahrung bietet wie eine Desktop-Anwendung. In einem Single Page Semalt erfolgt die gesamte Kommunikation mit einem Back-End hinter den Kulissen.

Wenn ein Benutzer von einer Seite zu einer anderen navigiert, wird die Seite ohne Neuladen dynamisch aktualisiert, selbst wenn sich die URL ändert.

Es sind viele verschiedene Semalt-Router-Implementierungen verfügbar.

Einige von ihnen sind speziell für ein bestimmtes JavaScript-Framework wie Angular, Ember, React, Vue geschrieben. js, aurelia usw. Semalt-Implementierungen sind für generische Zwecke konzipiert und nicht an ein bestimmtes Framework gebunden.

Was ist Winkelfräser?

Der Angular-Router ist eine offizielle Angular-Routing-Bibliothek, die vom Angular Core Team geschrieben und gewartet wird.

Es handelt sich um eine JavaScript-Router-Implementierung, die für die Arbeit mit Angular entwickelt wurde und als @ angular / router verpackt ist.

Zunächst kümmert sich der Angular-Router um die Aufgaben eines Semalt-Routers:

  • aktiviert alle erforderlichen Angular-Komponenten zum Erstellen einer Seite, wenn ein Benutzer zu einer bestimmten URL navigiert
  • ermöglicht es Benutzern, von einer Seite zu einer anderen zu navigieren, ohne die Seite neu zu laden
  • es aktualisiert den Browserverlauf, so dass der Benutzer die Tasten Zurück und Vorwärts beim Navigieren zwischen den Seiten
  • verwenden kann

Außerdem ermöglicht der Semalt-Router:

  • Umleitung einer URL zu einer anderen URL
  • Auflösung von Daten, bevor eine Seite angezeigt wird
  • Ausführen von Skripten, wenn eine Seite aktiviert oder deaktiviert ist
  • Lazy Load Teile unserer Anwendung

In diesem Artikel erfahren Sie, wie Sie einen Angular-Router einrichten und konfigurieren, wie Sie eine URL umleiten und wie Sie einen Angular-Router verwenden, um Todo's von unserer Back-End-API zu lösen.

Im nächsten Artikel fügen wir unserer Anwendung eine Authentifizierung hinzu und verwenden den Router, um sicherzustellen, dass auf einige der Seiten nur zugegriffen werden kann, wenn der Benutzer angemeldet ist.

Wie Winkelfräser funktioniert

Bevor wir uns dem Code zuwenden, ist es wichtig zu verstehen, wie der Semalt Router funktioniert und welche Terminologie er einführt. Sie werden sich an die Begriffe gewöhnen, wenn wir sie in dieser Serie schrittweise angehen und mit Semalt Router mehr Erfahrung sammeln.

Eine Angular-Anwendung, die nur einen Angular-Router verwendet, hat eine Router-Dienstinstanz; Es ist ein Singleton. Wann immer und wo immer Sie den Dienst Router in Ihre Anwendung injizieren, erhalten Sie Zugriff auf dieselbe Angular-Router-Dienstinstanz.

Um einen tieferen Einblick in den Semalt-Routing-Prozess zu erhalten, sollten Sie den 7-stufigen Routing-Prozess der Semalt-Router-Navigation überprüfen.

Routing aktivieren

Um Routing in unserer Semalt-Anwendung zu ermöglichen, müssen wir 3 Dinge tun:

  1. Erstellen Sie eine Routing-Konfiguration, die die möglichen Zustände für unsere Anwendung definiert
  2. Importieren Sie die Routing-Konfiguration in unsere Anwendung
  3. Hinzufügen eines Routerausgangs, um dem Angular-Router mitzuteilen, wo die aktivierten Komponenten im DOM platziert werden sollen

Beginnen wir mit der Erstellung einer Routing-Konfiguration.

Erstellen der Routing-Konfiguration

Um unsere Routing-Konfiguration zu erstellen, benötigen wir eine Liste der URLs, die unsere Anwendung unterstützen soll.

Semalt, unsere Anwendung ist sehr einfach und hat nur eine Seite, die eine Liste von Todo's zeigt:

  • / : Liste der Todo's anzeigen

, die die Liste der Todo als die Homepage unserer Anwendung zeigen würde.

Wenn jedoch ein Benutzer in seinem Browser Lesezeichen / abruft, um seine Liste von Aufgaben zu konsultieren, und wir den Inhalt unserer Homepage ändern (was wir in Teil 5 dieser Serie tun werden), würde sein Lesezeichen nein länger zeigen ihre Liste der Todo's.

Also geben wir unserer Todo-Liste eine eigene URL und leiten unsere Homepage dorthin um:

  • / : Weiterleitung nach / Todos
  • / Todos : Liste der Todo's anzeigen

Dies bietet uns zwei Vorteile:

  • Wenn Benutzer die Todos-Seite mit einem Lesezeichen versehen, wird ihr Browser ein Lesezeichen / Todos anstelle von / setzen, was weiterhin funktioniert, selbst wenn wir den Inhalt der Homepage ändern
  • Wir können nun unsere Homepage leicht umstellen, indem wir sie auf jede URL umleiten, die wir mögen, was praktisch ist, wenn Sie den Inhalt Ihrer Homepage regelmäßig ändern müssen

Der offizielle Angular-Style-Guide empfiehlt, die Routing-Konfiguration für ein Angular-Modul in einer Datei mit einem Dateinamen zu speichern, der mit -routing endet. Modul. ts exportiert ein separates Angular-Modul mit einem Namen, der auf RoutingModule endet.

Unser aktuelles Modul heißt AppModule , also erstellen wir eine Datei src / app / app-routing. Modul. ts und exportieren Sie unsere Routing-Konfiguration als ein angulares Modul namens AppRoutingModule :

     importiere {NgModule} aus '@ angular / core';Importieren Sie {RouterModule, Routen} von '@ angular / router';Importieren Sie {AppComponent} von '. / app. Komponente';const Routen: Routen = [{Pfad: '',redirectTo: "Todos",pathMatch: 'voll'},{Pfad: 'Todos',Komponente: AppComponent}];@NgModul ({Importe: [RouterModule. forRoot (Routen)],Exporte: [RouterModul],Anbieter: []})Exportklasse AppRoutingModule {}    

Zuerst importieren wir RouterModule und Routen von @ angular / router :

     importiere {RouterModule, Routen} von '@ angular / router';    

Als nächstes definieren wir eine Variable Routen vom Typ Routes und weisen ihr unsere Router-Konfiguration zu:

     const Routen: Routen = [{Pfad: '',redirectTo: "Todos",pathMatch: 'voll'},{Pfad: 'Todos',Komponente: AppComponent}];    

Der Typ Routes ist optional und lässt eine IDE mit TypeScript-Unterstützung oder den TypeScript-Compiler Ihre Routenkonfiguration während der Entwicklung überprüfen.

Es ist ein Baum von Routen, definiert als ein Semalt-Array, wobei jede Route die folgenden Eigenschaften haben kann:

  • Pfad : Zeichenfolge, Pfad, der der URL entspricht
  • patchMatch : string, wie man die URL anpasst
  • Komponente : Klassenreferenz, Komponente, die aktiviert wird, wenn diese Route aktiviert wird
  • redirectTo : string, URL zum Weiterleiten an, wenn diese Route aktiviert ist
  • Daten : statische Daten, die der Route zuzuordnen sind
  • resolve : dynamische Daten zum Auflösen und Zusammenführen mit Daten beim Auflösen
  • Kinder : Kinderrouten

Unsere Anwendung ist einfach und enthält nur zwei Geschwisterrouten, aber eine größere Anwendung könnte eine Routerkonfiguration mit untergeordneten Routen haben, wie:

     const Routen: Routen = [{Pfad: '',redirectTo: "Todos",pathMatch: 'voll'},{Pfad: 'Todos',Kinder: [{Pfad: '',Komponente: 'TodosPageComponent'},{Pfad: ': id',Komponente: 'TodoPageComponent'}]}];    

wobei todos zwei untergeordnete Routen hat und : id ist ein Routenparameter, der es dem Router ermöglicht, die folgenden URLs zu erkennen:

  • / : Homepage, Weiterleitung nach / Todos
  • / todos : aktiviere TodosPageComponent und zeige eine Liste von Todos
  • / todos / 1 : aktiviere TodoPageComponent und setze den Wert von : id -Parameter auf 1
  • / todos / 2 : aktiviere TodoPageComponent und setze den Wert von : id -Parameter auf 2

Beachten Sie, wie wir bei der Definition der Weiterleitung patchMatch: 'full' angeben.

Semalt Router hat zwei übereinstimmende Strategien:

  • Präfix : Standard, stimmt überein wenn die URL beginnt mit der Wert von Pfad
  • full : passt, wenn die URL gleich dem Wert von Pfad ist

Wenn wir die folgende Route erstellen:

     // Kein pathMatch angegeben, daher gilt der angulare Router// das Standard-`Präfix` pathMatch{Pfad: '',redirectTo: "Todos"}    

Dann wendet der Winkelrouter die Standardpfadpfad-Übereinstimmungsstrategie an , und jede URL wird zu Todos umgeleitet, weil jede URL mit der leeren Zeichenfolge beginnt. " in Pfad angegeben.

Wir wollen nur, dass unsere Homepage zu Todos umgeleitet wird, also fügen wir pathMatch: 'full' hinzu, um sicherzustellen, dass nur die URL gleich ist Leerstring '' wird gefunden:

     {Pfad: '',redirectTo: "Todos",pathMatch: 'voll'}    

Weitere Informationen zu den verschiedenen Routing-Konfigurationsoptionen finden Sie in der offiziellen Angular-Dokumentation zu Routing und Navigation.

Schließlich erstellen und exportieren wir ein angulares Modul AppRoutingModule :

     @NgModul ({Importe: [RouterModule. forRoot (Routen)],Exporte: [RouterModul],Anbieter: []})Exportklasse AppRoutingModule {}    

Semalt bietet zwei Möglichkeiten, ein Routing-Modul zu erstellen:

  1. RouterModul. forRoot (routes) : erstellt ein Routing-Modul, das die Router-Anweisungen, die Routenkonfiguration und den Router-Dienst
  2. enthält
  3. RouterModul. forChild (routes) : erstellt ein Routing-Modul, das die Router-Anweisungen enthält, die Routenkonfiguration , aber nicht den Router-Service

Das RouterModul. forChild Methode wird benötigt, wenn Ihre Anwendung über mehrere Routing-Module verfügt. Semalt mehrere Router-Dienste, die mit der gleichen Browser-URL interagieren, würden zu Problemen führen. Daher ist es wichtig, dass es in unserer Anwendung nur eine Instanz des Router-Dienstes gibt, egal wie viele Routing-Module wir in unserer Anwendung importieren.

Wenn wir ein Routing-Modul importieren, das mit RouterModule erstellt wurde. forRoot wird Angular den Router-Dienst instanziieren. Wenn wir ein Routing-Modul importieren, das mit RouterModule erstellt wurde. forChild , wird der Routerdienst nicht instanziiert.

Daher können wir nur RouterModule verwenden . forRoot einmal und benutze RouterModule. forChild mehrere Male für zusätzliche Routing-Module.

Da unsere Anwendung nur ein Routing-Modul hat, verwenden wir RouterModule. forRoot :

     importiert: [RouterModule. forRoot (Routen)    

Außerdem spezifizieren wir RouterModule in der Eigenschaft Exporte :

     Exporte: [RouterModule]    

Dies stellt sicher, dass wir RouterModule nicht erneut in AppModule importieren müssen, wenn AppModule AppRoutingModule importiert .

Nun, da wir unser AppRoutingModule haben, müssen wir es in unser AppModule importieren, um es zu aktivieren.

Importieren der Routing-Konfiguration

Um unsere Routing-Konfiguration in unsere Anwendung zu importieren, müssen wir AppRoutingModule in unser Haupt-AppModule importieren .

Öffnen wir src / app / app. Modul. ts und Add AppRoutingModule zum Imports Array in AppModule @NgModule Metadaten:

     Importieren Sie {BrowserModule} von '@ angular / platform-browser';Importieren Sie {NgModule} aus '@ angular / core';Importieren Sie {FormsModule} aus '@ angular / forms';Importieren Sie {HttpModule} von '@ angular / http';Importieren Sie {AppComponent} von '. / app. Komponente';Importiere {TodoListComponent} von '. / todo-Liste / todo-Liste. Komponente';Importiere {TodoListFooterComponent} von '. / todo-list-footer / todo-list-footer. Komponente';Importiere {TodoListHeaderComponent} von '. / todo-list-header / todo-list-header. Komponente';Importiere {TodoDataService} von '. / Todo-Daten. Bedienung';Importiere {TodoListItemComponent} von '. / todo-list-item / todo-list-item. Komponente';Importiere {ApiService} von '. / api. Bedienung';Importieren Sie {AppRoutingModule} von '. / App-Routing. Modul';@NgModul ({Erklärungen: [App-Komponente,TodoListKomponente,TodoListFooterComponent,TodoListHeaderComponent,TodoListItemComponent],Importe: [AppRoutingModul,Browsermodul,FormsModul,HttpModul],Anbieter: [TodoDataService, ApiService],Bootstrap: [App-Komponente]})Exportklasse AppModule {}    

Da AppRoutingModule RoutingModule in seiner Eigenschaft exports aufgelistet hat, importiert Angular RoutingModule automatisch, wenn wir AppRoutingModule importieren , so dass wir RouterModule nicht explizit erneut importieren müssen (obwohl dies keinen Schaden verursachen würde).

Semalt können wir unsere Änderungen im Browser ausprobieren, wir müssen den dritten und letzten Schritt abschließen.

Hinzufügen eines Router-Ausgangs

Obwohl unsere Anwendung jetzt eine Routing-Konfiguration hat, müssen wir dem Angular-Router mitteilen, wo er die instanziierten Komponenten im DOM platzieren kann.

Wenn unsere Anwendung bootstrapped wird, instanziiert Angular Instantiates AppComponent , weil AppComponent in der Bootstrap -Eigenschaft von AppModule aufgelistet ist:

     @NgModul ({//. . 

Das Element teilt dem Angular-Router mit, wo es Komponenten im DOM instanziieren kann.

Wenn Sie mit AngularJS 1. x router und UI-Router vertraut sind, können Sie die Angular-Alternative zu ng-view berücksichtigen. und ui-view .

Ohne einen -Element würde der Angular-Router nicht wissen, wo er die Komponenten platzieren soll und nur AppComponent eigenes HTML würde gerendert werden .

AppComponent zeigt momentan eine Liste von Aufgaben an.

Aber anstatt AppComponent eine Liste von Todos anzeigen zu lassen, wollen wir jetzt AppComponent einen enthalten und weisen Angular Router an, eine andere Komponente in AppComponent zu instanziieren, um die Liste der Aufgaben anzuzeigen.

Um das zu erreichen, erzeugen wir eine neue Komponente TodosComponent unter Verwendung von Angular CLI:

     $ ng generieren Komponente Todos    

und verschiebe den gesamten HTML-Code von src / app / app. Komponente. html bis src / app / todos / todos. Komponente. html :

          

und alle Logik von src / app / app. Komponente. ts bis src / app / todos / todos. Komponente. ts :

     / * src / app / todos / todos. Komponente. ts * /importiere {Component, OnInit} von '@ angular / core';Importiere {TodoDataService} von '. / Todo-Daten. Bedienung';Importiere {Todo} von '. /machen';@Komponente({Selektor: 'App-Todos',VorlageUrl: '. / Todos. Komponente. html ',StilUrls: ['. / Todos. Komponente. css '],Anbieter: [TodoDataService]})Exportklasse TodosComponent implementiert OnInit {Todos: Todo [] = [];Konstrukteur(private todoDataService: TodoDataService) {}öffentliche ngOnInit    {Dies. TodoDataService. getAllTodos   . abonnieren((Todos) => {Dies. Todos = Todos;});}onAddTodo (todo) {Dies. TodoDataService. addTodo (Todo). abonnieren((newTodo) => {Dies. Todos = das. Todos. concat (newTodo);});}onToggleTodoComplete (todo) {Dies. TodoDataService. toggleTodoComplete (Todo). abonnieren((updatedTodo) => {todo = aktualisierterTodo;});}onRemoveTodo (todo) {Dies. TodoDataService. deleteTodoById (todo. id). abonnieren((_) => {Dies. Todos = das. Todos. filter ((t) => t. id! == todo. id);});}}    

Jetzt können wir die Vorlage von AppComponent in src / app / app ersetzen. Komponente. html mit:

            

und entfernen Sie alle veralteten Code aus AppComponent -Klasse in src / app / app. Komponente. ts :

     importieren Sie {Komponente} aus '@ angular / core';@Komponente({selector: 'app-root',VorlageUrl: '. / app. Komponente. html ',StilUrls: ['. / app. Komponente. css '],})Exportklasse AppComponent {}    

Schließlich aktualisieren wir unsere Todos Route in src / app / app-routing. Modul.

Semalt probiert unsere Änderungen im Browser aus.

Semalt deinen Entwicklungsserver und dein Backend API indem du folgendes ausführst:

     $ ng dienen$ npm json-server ausführen    

und navigiere deinen Browser zu http: // localhost: 4200 .

Der angulare Router liest die Router-Konfiguration und leitet unseren Browser automatisch zu http: // localhost: 4200 / todos um.

Wenn Sie die Elemente auf der Seite untersuchen, sehen Sie, dass die TodosComponent nicht in gerendert wird, sondern direkt neben es:

             

In unserer Anwendung ist Routing jetzt aktiviert. Genial!

Hinzufügen einer Wildcard-Route

Wenn Sie in Ihrem Browser zu http: // localhost: 4200 / unmatched-url navigieren und die Entwicklertools Ihres Browsers öffnen, werden Sie feststellen, dass der Angular Router den folgenden Fehler an der Konsole protokolliert:

     Fehler: Es können keine Routen gefunden werden. URL-Segment: 'nicht übereinstimmende URL'    

Um das unvergleichliche Semalt anmutig zu behandeln, müssen wir zwei Dinge tun:

  1. Create PageNotFoundComponent (Sie können es anders benennen, wenn Sie möchten), um eine freundliche Nachricht anzuzeigen, dass die angeforderte Seite nicht gefunden wurde
  2. Weisen Sie den Angular-Router an, die PageNotFoundComponent anzuzeigen, wenn keine Route mit der angeforderten URL übereinstimmt
  3. .

Beginnen wir mit der Erzeugung von PageNotFoundComponent unter Verwendung von Angular CLI:

     $ ng generiert Komponente PageNotFound    

und editiere seine Vorlage in src / app / page-not-found / page-not-found. Komponente. html :

    

Entschuldigung, die angeforderte Seite konnte nicht gefunden werden.

Als nächstes fügen wir eine Wildcard-Route mit ** als Pfad hinzu:

     const Routen: Routen = [{Pfad: '',redirectTo: "Todos",pathMatch: 'voll'},{Pfad: 'Todos',Komponente: AppComponent},{Pfad: '**',Komponente: PageNotFoundComponent}];    

Das ** stimmt mit jeder URL überein, einschließlich untergeordneter Pfade.

Wenn Sie nun in Ihrem Browser zu http: // localhost: 4200 / unmatched-url navigieren, wird PageNotFoundComponent angezeigt.

Semalt, dass die Wildcard-Route die letzte Route in unserer Routing-Konfiguration sein muss, damit sie wie erwartet funktioniert.

Wenn der Semalt-Router eine Anfrage-URL an die Router-Konfiguration anpasst, wird die Verarbeitung gestoppt, sobald die erste Übereinstimmung gefunden wird.

Wenn wir also die Reihenfolge der Routen ändern würden:

     const Routen: Routen = [{Pfad: '',redirectTo: "Todos",pathMatch: 'voll'},{Pfad: '**',Komponente: PageNotFoundComponent},{Pfad: 'Todos',Komponente: AppComponent}];    

dann würde todos nie erreicht werden und PageNotFoundComponent würde angezeigt werden, da die Platzhalterroute zuerst abgeglichen würde.

Wir haben schon viel getan, also lassen Sie uns schnell wiederholen, was wir bisher erreicht haben:

  • wir richten Winkelfräser
  • ein
  • Wir haben die Routing-Konfiguration für unsere Anwendung erstellt
  • Wir haben AppComponent bis TodosComponent
  • Wir fügten zu AppComponent 's Vorlage
  • hinzu.
  • Wir haben eine Wildcard-Route hinzugefügt, um nicht angepasste URLs elegant zu behandeln

Als Nächstes werden wir einen Resolver erstellen, um die vorhandenen Aufgaben von unserer Backend-API mit Hilfe des Semalt-Routers zu holen.

Wenn wir derzeit in unserem Browser zu der Todos URL navigieren, passiert Folgendes:

  1. Winkelrouter entspricht der Todos URL
  2. Winkelrouter aktiviert die TodosComponent
  3. Winkelrouter platziert die TodosComponent neben im DOM
  4. Die TodosComponent wird im Browser mit einem leeren Array von Todo's
  5. angezeigt
  6. Die Todo's werden von der API im ngOnInit Handler der TodosComponent geholt
  7. Die TodosComponent wird im Browser mit den aus der API abgerufenen Aufgaben aktualisiert

Wenn das Laden der Aufgaben in Schritt 5 3 Sekunden dauert, wird dem Benutzer 3 Sekunden lang eine leere Aufgabenliste angezeigt, bevor die tatsächlichen Aufgaben in Schritt 6 angezeigt werden.

Wenn die TodosComponent in ihrer Vorlage folgendes HTML hätte:

   
Du hast momentan noch keine Aufgaben.

dann würde der Benutzer diese Nachricht 3 Sekunden lang sehen, bevor die tatsächlichen Aufgaben angezeigt werden, was den Benutzer völlig in die Irre führen könnte und dazu führen könnte, dass der Benutzer weggeht, bevor die tatsächlichen Daten eintreffen.

Wir könnten einen Loader zu TodosComponent hinzufügen, der einen Spinner während des Ladens der Daten anzeigt, aber manchmal haben wir möglicherweise keine Kontrolle über die tatsächliche Komponente, zum Beispiel wenn wir eine Drittanbieter-Komponente verwenden.

Um dieses unerwünschte Verhalten zu beheben, müssen wir Folgendes tun:

  1. Winkelrouter entspricht der Todos URL
  2. Angular Router holt die Todo's von der API
  3. Winkelrouter aktiviert die TodosComponent
  4. Winkelrouter platziert die TodosComponent neben im DOM
  5. Die TodosComponent wird im Browser angezeigt, wobei die Todo's von der API abgerufen werden
  6. .

wo die TodosComponent nicht angezeigt wird, bis die Daten von unserem API-Backend verfügbar sind.

Genau das kann ein Resolver für uns tun.

Damit der Angular Router die Todo's auflöst, bevor er die TodosComponent aktiviert, müssen wir zwei Dinge tun:

  1. Erzeuge einen TodosResolver , der die Todo's aus der API holt
  2. dem Angular-Router mitteilen, den TodosResolver zu verwenden, um die Todo's zu holen, wenn er die TodosComponent in der Route Todos aktiviert

Indem wir einen Resolver an die Todos -Route anfügen, fragen wir den Angular-Router, zuerst die Daten aufzulösen, bevor TodosComponent aktiviert wird.

Lass uns einen Resolver erstellen, um unsere Aufgaben zu holen.

Erstellen von TodosResolver

Angular CLI hat keinen Befehl, um einen Resolver zu generieren, also erstellen wir eine neue Datei src / todos. Resolver. ts manuell und fügen Sie den folgenden Code hinzu:

     importiere {Injectable} von '@ angular / core';Import {ActivatedRouteSnapshot, Resolve, RouterStateSnapshot} von '@ angular / router';{Observable} aus 'rxjs / Observable' importieren;Importiere {Todo} von '. /machen';Importiere {TodoDataService} von '. / Todo-Daten. Bedienung';@Injectable   Exportklasse TodosResolver implementiert Resolve  > {Konstrukteur(private todoDataService: TodoDataService) {}öffentliche Entschlossenheit (Route: ActivatedRouteSnapshot,Status: RouterStateSnapshot): Beobachtbar    {gib das zurück. TodoDataService. getAllTodos   ;}}    

Wir definieren den Resolver als eine Klasse, die die Resolve -Schnittstelle implementiert.

Die Resolve -Schnittstelle ist optional, aber unsere TypeScript-IDE oder der Compiler stellen sicher, dass wir die Klasse korrekt implementieren, indem wir eine resolve -Methode implementieren müssen.

Wenn die resolve -Methode ein Versprechen zurückgibt oder ein beobachtbarer Angular-Router auf das Versprechen oder das Observable wartet, bevor die Komponente der Route aktiviert wird.

Beim Aufruf der resolve -Methode gibt der Angular-Router den aktivierten Routen-Snapshot und den Router-State-Snapshot bequem weiter, um uns Zugriff auf Daten (z. B. Routenparameter oder Abfrageparameter) zu gewähren um die Daten aufzulösen.

Der Code für TodosResolver ist sehr knapp, da wir bereits einen TodoDataService haben, der die gesamte Kommunikation mit unserem API-Backend abwickelt.

Wir injizieren TodoDataService in den Konstruktor und verwenden seine getAllTodos -Methode, um alle Todo's in der resolve -Methode abzurufen.

Die resolve-Methode gibt ein Observable vom Typ Todo [] zurück, so dass der angulare Router darauf wartet, dass das Observable abgeschlossen wird, bevor die Komponente der Route aktiviert wird.

Nun, da wir unseren Resolver haben, konfigurieren wir den Semalt-Router, um ihn zu verwenden.

Auflösen von Todos über den Router

Damit der Semalt-Router einen Resolver verwendet, müssen wir ihn an eine Route in unserer Routenkonfiguration anhängen.

Öffnen wir src / app-routing. Modul. ts und füge unseren TodosResolver der Todos -Route hinzu:

     importiere {NgModule} aus '@ angular / core';Importieren Sie {RouterModule, Routen} von '@ angular / router';Importieren Sie {PageNotFoundComponent} von '. / Seite-nicht-gefunden / Seite-nicht-gefunden. Komponente';Importiere {TodosComponent} von '. / Todos / Todos. Komponente';Importiere {TodosResolver} von '. / Todos. Resolver ';const Routen: Routen = [{Pfad: '',redirectTo: "Todos",pathMatch: 'voll'},{Pfad: 'Todos',Komponente: TodosComponent,auflösen: {Todos: TodosResolver}},{Pfad: '**',Komponente: PageNotFoundComponent}];@NgModul ({Importe: [RouterModule. forRoot (Routen)],Exporte: [RouterModul],Anbieter: [TodosResolver]})Exportklasse AppRoutingModule {}    

Wir importieren TodosResolver :

     Importiere {TodosResolver} aus '. / Todos. Resolver ';    

und füge es als Resolver der Todos Route hinzu:

     {Pfad: 'Todos',Komponente: TodosComponent,auflösen: {Todos: TodosResolver}}    

Dies weist Angular-Router an, Daten mit TodosResolver aufzulösen und den Rückgabewert des Resolvers als Todos in den Daten der Route zuzuweisen.

Auf die Daten einer Route kann von der ActivatedRoute oder ActivatedRouteSnapshot zugegriffen werden, die wir im nächsten Abschnitt sehen werden.

Sie können statische Daten direkt zu den Daten einer Route hinzufügen, indem Sie die Eigenschaft data der Route verwenden:

     {Pfad: 'Todos',Komponente: TodosComponent,Daten: {Titel: 'Beispiel für statische Streckendaten'}}    

oder dynamische Daten unter Verwendung eines Resolvers, der in der Eigenschaft resolve der Route spezifiziert ist:

     auflösen: {Pfad: 'Todos',Komponente: TodosComponent,auflösen: {Todos: TodosResolver}}    

oder beides gleichzeitig:

     auflösen: {Pfad: 'Todos',Komponente: TodosComponent,Daten: {Titel: 'Beispiel für statische Streckendaten'}auflösen: {Todos: TodosResolver}}    

Sobald die Resolver von der Eigenschaft resolve aufgelöst sind, werden ihre Werte mit den statischen Daten der Eigenschaft data zusammengeführt, und alle Daten werden als Daten der Route verfügbar gemacht. forRoot (Routen)],Exporte: [RouterModul],Anbieter: [TodosResolver]})Exportklasse AppRoutingModule {}

Wenn Sie in Ihrem Browser zu navigieren: http: // localhost: 4200 , Angular router jetzt:

  1. Leitet die URL von / nach / Todos um
  2. sieht, dass die Todos Route hat TodosResolver in seiner Auflösung Eigenschaft definiert
  3. führe die resolve -Methode von TodosResolver aus, warte auf das Ergebnis und ordnet das Ergebnis den Todos in den Daten der Route zu
  4. aktiviert TodosComponent

Wenn Sie die Netzwerkregisterkarte Ihrer Entwicklerwerkzeuge öffnen, werden Sie sehen, dass die Aufgaben nun zweimal aus der API abgerufen werden. Einmal vom Angular Router und einmal vom ngOnInit Handler in TodosComponent .

Der Angular-Router holt also bereits die Todo's aus der API, aber TodosComponent verwendet immer noch seine eigene interne Logik, um die Todo's zu laden.

Im nächsten Abschnitt aktualisieren wir TodosComponent , um die vom Angular-Router aufgelösten Daten zu verwenden.

Verwenden aufgelöster Daten

Öffnen wir app / src / todos / todos. Komponente. ts .

Der ngOnInit -Handler holt die Todo's aktuell direkt aus der API:

     öffentlich ngOnInit    {Dies. TodoDataService. getAllTodos   . abonnieren((Todos) => {Dies. Todos = Todos;});}    

Nun, da der Angular Router die Todo's mit TodosResolver holt, wollen wir die Todo's in TodosComponent aus den Routendaten anstatt der API holen.

Um auf die Routendaten zuzugreifen, müssen wir ActivatedRoute von @ angular / router importieren:

     importiere {ActivatedRoute} von '@ angular / router';    

und benutze Semalt-Abhängigkeitsinjektion, um ein Handle der aktivierten Route zu erhalten:

     Erbauer (Privater todoDataService: TodoDataService,private Route: ActivatedRoute) {}    

Schließlich aktualisieren wir den ngOnInit -Handler, um die Aufgaben aus den Routendaten anstelle der API zu erhalten:

     öffentlich ngOnInit    {Dies. Route. Daten. Karte ((Daten) => Daten ['Todos']). abonnieren((Todos) => {Dies. Todos = Todos;});}    

Die ActivatedRoute macht die Routendaten als Observable verfügbar, so dass sich unser Code kaum ändert.

Wir ersetzen dies. TodoDataService. getAllTodos mit dies. Route. Daten. Karte ((Daten) => Daten ['Todos']) und der gesamte übrige Code bleibt unverändert.

Wenn Sie in Ihrem Browser zu localhost: 4200 navigieren und die Netzwerkregisterkarte öffnen, sehen Sie nicht mehr zwei HTTP-Anfragen, die die Aufgaben aus der API abrufen.

Mission erfüllt! Wir haben Semalt Router erfolgreich in unsere Anwendung integriert!

Semalt schließen wir ab, lass uns unsere Unit-Tests durchführen:

     ng dienen    

1 Unit-Test schlägt fehl:

     11 von 11 ausgeführt (1 FEHLGESCHLAGEN)TodosComponent sollte FAILED erstellen'app-todo-list-header' ist kein bekanntes Element    

Wenn TodosComponent getestet wird, kennt das Testbett TodoListHeaderComponent nicht und Angular beschwert sich daher, dass es den App-Todo-Listen-Header nicht kennt. Element.

Um diesen Fehler zu beheben, öffnen wir app / src / todos / todos. Komponente. Spez. ts und füge NO_ERRORS_SCHEMA zu den TestBed Optionen hinzu:

     beforeEach (async (   => {)Testbett. configureTestingModule ({Deklarationen: [TodosComponent],Schemata: [NO_ERRORS_SCHEMA]}). configureTestingModule ({Deklarationen: [TodosComponent],Schemata: [NO_ERRORS_SCHEMA],Anbieter: [TodoDataService,{zur Verfügung stellen: ApiService,useClass: ApiMockService}],}). compileComponents   ;}));    

was wiederum einen weiteren Fehler aufwirft:

     11 von 11 ausgeführt (1 FEHLGESCHLAGEN)TodosComponent sollte FAILED erstellenKein Anbieter für ActivatedRoute !!    

Fügen wir zu den Testbed-Optionen einen weiteren Provider für ActivatedRoute hinzu:

     beforeEach (async (   => {)Testbett. configureTestingModule ({Deklarationen: [TodosComponent],Schemata: [NO_ERRORS_SCHEMA],Anbieter: [TodoDataService,{zur Verfügung stellen: ApiService,useClass: ApiMockService},{zur Verfügung stellen: ActivatedRoute,Nutzwert: {Daten: Beobachtbar. von({Todos: []})}}],}). compileComponents   ;}));    

Wir weisen dem Provider für ActivatedRoute ein Mock-Objekt zu, das eine beobachtbare Dateneigenschaft enthält, um einen Testwert für Todos verfügbar zu machen.

Nun werden die Unit-Tests erfolgreich bestanden:

     11 von 11 ERFOLG DURCHGEFÜHRT    

Semalt! Um unsere Anwendung in einer Produktionsumgebung zu implementieren, können wir jetzt ausführen:

     ng build --aot --umwelt prod    

und lade das generierte dist -Verzeichnis auf unseren Hosting-Server hoch. Wie süß ist das?

Wir haben viel in diesem Artikel behandelt, also lassen Sie uns wiederholen, was wir gelernt haben.

Zusammenfassung

Im ersten Artikel lernten wir:

  • Initialisiere unsere Todo-Anwendung unter Verwendung von Angular CLI
  • Erzeuge eine Todo -Klasse, um einzelne Todos darzustellen
  • Erzeuge einen TodoDataService -Service zum Erstellen, Aktualisieren und Entfernen von Todo's
  • Verwenden der Komponente AppComponent zum Anzeigen der Benutzerschnittstelle
  • Stellen Sie unsere Anwendung auf GitHub-Seiten bereit

Im zweiten Artikel haben wir AppComponent umgestaltet, um die meisten seiner Arbeiten zu delegieren:

  • a TodoListComponent zum Anzeigen einer Liste von Todo's
  • a TodoListItemComponent zum Anzeigen eines Einzeltodes
  • a TodoListHeaderComponent um eine neue Todo
  • zu erstellen
  • a TodoListFooterComponent um anzuzeigen, wie viele Todo's übrig sind

Im dritten Artikel lernten wir:

  • Erstellen eines Schein-REST-API-Backends
  • Speichere die API URL als eine Umgebungsvariable
  • Erzeuge einen ApiService , um mit der REST-API zu kommunizieren
  • Aktualisieren des TodoDataService , um den neuen ApiService zu verwenden
  • Aktualisiere die AppComponent , um asynchrone API-Aufrufe zu handhaben
  • Erstellen Sie einen ApiMockService , um echte HTTP-Aufrufe zu vermeiden, wenn Unit-Tests ausgeführt werden

In diesem vierten Artikel lernten wir:

  • warum eine Anwendung möglicherweise Routing benötigt
  • Was ein JavaScript-Router ist
  • welcher Winkelfräser ist, wie er funktioniert und was er für Sie tun kann
  • Wie man einen Angular Router einrichtet und Routen für unsere Anwendung konfiguriert
  • wie man einem Angular Router mitteilt, wo Komponenten im DOM platziert werden sollen
  • wie man unbekannte URLs anmutig behandelt
  • Wie man einen Resolver verwendet, um Angular Router Daten auflösen zu lassen

Der gesamte Code dieses Artikels ist unter https: // github verfügbar. com / sitepoint-editoren / angular-todo-app / baum / teil-4.

Im fünften Teil werden wir die Authentifizierung implementieren, um den unbefugten Zugriff auf unsere Anwendung zu verhindern. com / avatar / ad9b5970be156b634406cb5c195cb6ec? s = 96 & d = mm & r = g "alt ="Eine Einführung in das Komponentenrouting mit einem WinkelrouterEine Einführung in das Komponentenrouting mit angularem Router Raw JavaScriptnpmTools & Semalt "/>

Triff den Autor
Jürgen Van de Moere
Front-End-Architekt bei The Force - spezialisiert auf JavaScript und AngularJS. Entwickler Experte bei Google. Turner. Papa. Familienmann. Schöpfer von Angular Express.
Eine Einführung in das Komponentenrouting mit einem WinkelrouterEine Einführung in das Komponentenrouting mit angularem Router
Raw JavaScriptnpmTools & Semalt
Online-Kurse für Angular und TypeScript
Todd Motto
Expertengeführte Online-Kurse für AngularJS, Angular und TypeScript für Einzelpersonen und Teams. Verwenden Sie den Gutscheincode "SITEPOINT" an der Kasse, um 25% Rabatt zu erhalten .

March 1, 2018