日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

angular复用路由组件_Angular Router的组件路由简介

發布時間:2024/1/8 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 angular复用路由组件_Angular Router的组件路由简介 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

angular復用路由組件

這是SitePoint Angular 2+教程的第4部分,有關如何使用Angular CLI創建CRUD應用程序。 在本文中,我們將介紹Angular Router,并了解當瀏覽器URL更改時它如何更新我們的應用程序,反之亦然。 我們還將學習如何使用路由器更新應用程序,以解析來自后端API的數據。

在第一部分中,我們學習了如何啟動和運行Todo應用程序并將其部署到GitHub頁面。 這樣做很好,但不幸的是,整個應用程序都擠在一個組件中。

在第二部分中,我們研究了模塊化程度更高的組件體系結構,并學習了如何將單個組件分解為較小的組件的結構化樹,這些樹更易于理解,重用和維護。

在第三部分中,我們更新了應用程序以使用RxJS和Angular的HTTP服務與REST API后端進行通信。

  • 第0部分— Ultimate Angular CLI參考指南
  • 第1部分-啟動并運行我們的Todo應用程序的第一個版本
  • 第2部分-創建單獨的組件以顯示待辦事項列表和一個待辦事項
  • 第3部分-更新Todo服務以與REST API通信
  • 第4部分-使用Angular路由器解析數據
  • 第5部分-添加身份驗證以保護私有內容
  • 第6部分—如何將Angular項目更新到最新版本。
  • 不用擔心 您無需遵循本教程的第一部分,第二部分或第三部分,就可以使第四部分有意義。 您可以簡單地獲取我們的倉庫的副本,從第三部分中檢出代碼,并以此作為起點。 下面將對此進行詳細說明。

    啟動并運行

    確保您已安裝最新版本的Angular CLI。 如果沒有安裝,則可以使用以下命令進行安裝:

    npm install -g @angular/cli@latest

    如果您需要刪除以前版本的Angular CLI,則可以執行以下操作:

    npm uninstall -g @angular/cli angular-cli npm cache clean npm install -g @angular/cli@latest

    之后,您將需要第三部分的代碼副本。 可以在GitHub上找到 。 本系列中的每篇文章在存儲庫中都有一個相應的標記,因此您可以在應用程序的不同狀態之間來回切換。

    我們在第三部分結尾并且在本文開始的代碼被標記為第三部分 。 本文結尾處的代碼被標記為part-4 。

    您可以將標簽視為特定提交ID的別名。 您可以使用git checkout在它們之間切換。 您可以在此處內容 。

    因此,要啟動并運行(安裝了最新版本的Angular CLI),我們可以這樣做:

    git clone git@github.com:sitepoint-editors/angular-todo-app.git cd angular-todo-app git checkout part-3 npm install ng serve

    然后訪問http:// localhost:4200 / 。 如果一切順利,您應該會看到正在運行的Todo應用程序。

    快速回顧

    這是第3部分結尾處的應用程序體系結構:

    在本文中,我們將:

    • 了解為什么應用程序可能需要路由
    • 了解什么是JavaScript路由器
    • 了解什么是Angular Router,它如何工作以及可以為您做什么
    • 設置Angular Router并為我們的應用程序配置路由
    • 創建一個解析器以從我們的REST API獲取待辦事項
    • 使用新的解析器更新我們的應用程序以獲取待辦事項。

    到本文結尾,您將了解:

    • 什么時候以及為什么您的應用程序可能需要路由
    • 服務器上的路由和瀏覽器中的路由之間的區別
    • 什么是Angular Router以及它可以為您的應用程序做什么
    • 如何設置角度路由器
    • 如何為您的應用程序配置路由
    • 如何告訴Angular Router在DOM中的何處放置組件
    • 如何妥善處理未知URL
    • 什么是解析器及其用途
    • 如何使用解析器使用Angular Router解析數據。

    所以,讓我們開始吧!

    為什么要布線?

    在當前狀態下,我們的Web應用程序未考慮瀏覽器URL。

    我們通過一個URL(例如http://localhost:4200訪問我們的應用程序,而我們的應用程序不知道其他任何URL(例如http://localhost:4200/todos 。

    免費學習PHP!

    全面介紹PHP和MySQL,從而實現服務器端編程的飛躍。

    原價$ 11.95 您的完全免費

    大多數Web應用程序需要支持不同的URL才能將用戶導航到應用程序中的不同頁面。 那就是路由器進來的地方。

    在傳統網站中,路由是由服務器上的路由器處理的:

  • 用戶單擊瀏覽器中的鏈接,導致URL更改
  • 瀏覽器向服務器發送HTTP請求
  • 服務器從HTTP請求中讀取URL并生成適當的HTTP響應
  • 服務器將HTTP響應發送到瀏覽器。
  • 在現代JavaScript Web應用程序中,路由通常由瀏覽器中JavaScript路由器處理。

    什么是JavaScript路由器?

    本質上,JavaScript路由器執行以下兩項操作:

  • 當瀏覽器URL更改時更新Web應用程序狀態
  • Web應用程序狀態更改時更新瀏覽器URL。
  • JavaScript路由器使我們能夠開發單頁應用程序(SPA)。

    SPA是一種Web應用程序,可提供類似于桌面應用程序的用戶體驗。 在SPA中,與后端的所有通信都在后臺進行。

    當用戶從一個頁面導航到另一頁面時,即使URL更改了,頁面也將動態更新而無需重新加載。

    有許多不同JavaScript路由器實現。

    其中一些是專門為某個JavaScript框架(例如Angular , Ember , React , Vue.js和Aurelia等) 編寫的 。其他實現是出于通用目的而構建的,并不與特定的框架綁定。

    什么是角路由器?

    Angular Router是Angular核心團隊編寫和維護的官方Angular路由庫。

    這是一個JavaScript路由器實現,旨在與Angular一起使用,并打包為@angular/router 。

    首先,Angular Router負責JavaScript路由器的職責:

    • 當用戶導航到某個URL時,它將激活所有必需的Angular組件以組成一個頁面
    • 它使用戶可以從一頁導航到另一頁而無需重新加載頁面
    • 它會更新瀏覽器的歷史記錄,以便用戶在頁面之間來回導航時可以使用后退和前進按鈕。

    此外,Angular Router還使我們能夠:

    • 將一個URL重定向到另一個URL
    • 在顯示頁面之前解析數據
    • 激活或停用頁面時運行腳本
    • 我們的應用程序的延遲加載部分。

    在本文中,我們將學習如何設置和配置Angular Router,如何重定向URL以及如何使用Angular Router通過后端API解析待辦事項。

    在下一篇文章中,我們將向我們的應用程序添加身份驗證,并使用路由器確保只有在用戶登錄后才能訪問某些頁面。

    角路由器如何工作

    在深入研究代碼之前,了解Angular Router的工作方式及其引入的術語非常重要。

    當用戶導航到頁面時,Angular Router依次執行以下步驟:

  • 它讀取用戶想要導航到的瀏覽器URL
  • 它應用URL重定向(如果已定義)
  • 它找出哪個路由器狀態對應于URL
  • 它運行在路由器狀態中定義的防護
  • 它解析路由器狀態所需的數據
  • 它激活Angular組件以顯示頁面
  • 它管理導航并在請求新頁面時重復上述步驟。
  • 為了完成其任務,Angular Router引入了以下術語和概念:

    • 路由器服務 :我們應用程序中的全局Angular路由器服務
    • 路由器配置 :定義我們的應用程序可以位于的所有可能的路由器狀態
    • 路由器狀態 :路由器在某個時間點的狀態,表示為激活的路由快照的樹
    • 激活的路由快照 :提供對路由器狀態節點的URL,參數和數據的訪問
    • guard :在加載,激活或停用路由時運行的腳本
    • 解析器 :在激活請求的頁面之前獲取數據的腳本
    • 路由器出口 :Angular Router可以在其中放置激活組件的DOM中的位置。

    不用擔心該術語聽起來很壓倒性。 當我們在本系列中逐步解決這些術語時,您會習慣這些術語,并且您在Angular Router上獲得了更多的經驗。

    使用Angular路由器的Angular應用程序只有一個路由器服務實例:這是一個單例。 無論何時何地在應用程序中注入Router服務,您都可以訪問同一Angular Router服務實例。

    要更深入地了解Angular路由過程,請確保查看Angular Router導航的7步路由過程 。

    啟用路由

    要在Angular應用程序中啟用路由,我們需要做三件事:

  • 創建一個路由配置,為我們的應用程序定義可能的狀態
  • 將路由配置導入我們的應用程序
  • 添加一個路由器出口,以告訴Angular Router將激活的組件放置在DOM中的何處。
  • 因此,讓我們從創建路由配置開始。

    創建路由配置

    要創建路由配置,我們需要一個我們希望應用程序支持的URL列表。

    當前,我們的應用程序非常簡單,只有一個頁面顯示待辦事項列表:

    • / :顯示待辦事項清單

    它將待辦事項列表顯示為應用程序的主頁。

    但是,當用戶在其瀏覽器中為/書簽以查看待辦事項列表時,如果我們更改了主頁的內容(我們將在本系列的第5部分中進行此操作),則他們的書簽將不再顯示待辦事項列表。

    因此,讓我們給待辦事項列出自己的URL并將我們的主頁重定向到該URL:

    • / :重定向到/todos
    • /todos :顯示待辦事項列表。

    這為我們提供了兩個好處:

    • 當用戶將待辦事項頁面添加為書簽時,即使我們更改了主頁內容,他們的瀏覽器也將/todos而不是/書簽,這將繼續按預期工作
    • 現在,我們可以通過將其重定向到我們喜歡的任何URL來輕松地更改主頁,如果您需要定期更改主頁內容,這將非常方便。

    官方Angular樣式指南建議將Angular模塊的路由配置存儲在文件名中,該文件名以-routing.module.ts結尾,該文件將導出一個單獨的Angular模塊,其名稱以RoutingModule結尾。

    當前的模塊名為AppModule ,因此我們創建了一個文件src/app/app-routing.module.ts并將路由配置導出為一個名為AppRoutingModule的Angular模塊:

    import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { AppComponent } from './app.component';const routes: Routes = [{path: '',redirectTo: 'todos',pathMatch: 'full'},{path: 'todos',component: AppComponent} ];@NgModule({imports: [RouterModule.forRoot(routes)],exports: [RouterModule],providers: [] }) export class AppRoutingModule { }

    首先,我們從@angular/router導入RouterModule和Routes :

    import { RouterModule, Routes } from '@angular/router';

    接下來,我們定義類型為Routes的可變routes ,并為其分配路由器配置:

    const routes: Routes = [{path: '',redirectTo: 'todos',pathMatch: 'full'},{path: 'todos',component: AppComponent} ];

    Routes類型是可選的,可讓具有TypeScript支持的IDE或TypeScript編譯器在開發過程中方便地驗證您的路由配置。

    路由器配置代表我們的應用程序可以處于的所有可能的路由器狀態。

    它是路由樹,定義為JavaScript數組,其中每個路由可以具有以下屬性:

    • path :字符串,匹配URL的路徑
    • pathMatch :字符串,如何匹配URL
    • component :類引用,激活此路由時要激活的組件
    • redirectTo :字符串,激活此路由后重定向到的URL
    • data :分配給路由的靜態數據
    • resolve解決動態數據并在解析后與數據合并
    • 兒童 :兒童路線。

    我們的應用程序很簡單,僅包含兩個同級路由,但是較大的應用程序可能具有帶有子路由的路由器配置,例如:

    const routes: Routes = [{path: '',redirectTo: 'todos',pathMatch: 'full'},{path: 'todos',children: [{path: '',component: 'TodosPageComponent'},{path: ':id',component: 'TodoPageComponent'}]} ];

    在這里, todos有兩個子路由,而:id是一個路由參數,使路由器能夠識別以下URL:

    • / :主頁,重定向到/todos
    • /todos :激活TodosPageComponent并顯示TodosPageComponent列表
    • /todos/1 :激活TodoPageComponent并將:id參數的值設置為1
    • /todos/2 :激活TodoPageComponent并將:id參數的值設置為2 。

    請注意,在定義重定向時,我們如何指定pathMatch: 'full' 。

    Angular Router具有兩種匹配策略:

    • prefix :默認值,當URL path的值開頭時匹配
    • full :URL 等于 path的值時匹配。

    我們可以創建以下路線:

    // no pathMatch specified, so Angular Router applies // the default `prefix` pathMatch {path: '',redirectTo: 'todos' }

    在這種情況下,Angular Router應用默認的prefix路徑匹配策略,并且每個URL都重定向到todos因為每個URL都以path指定的空字符串'' 開頭

    我們只希望將主頁重定向到todos ,所以我們添加pathMatch: 'full'以確保僅匹配等于空字符串''的URL:

    {path: '',redirectTo: 'todos',pathMatch: 'full' }

    要了解有關不同的路由配置選項的更多信息,請查看有關路由和導航的官方Angular文檔。

    最后,我們創建并導出一個Angular模塊AppRoutingModule :

    @NgModule({imports: [RouterModule.forRoot(routes)],exports: [RouterModule],providers: [] }) export class AppRoutingModule { }

    有兩種創建路由模塊的方法:

  • RouterModule.forRoot(routes) :創建一個路由模塊,其中包括路由器指令,路由配置路由器服務
  • RouterModule.forChild(routes) :創建一個路由模塊,其中包含路由器指令,路由配置但不包括路由器服務。
  • 當您的應用程序具有多個路由模塊時,需要RouterModule.forChild()方法。

    請記住,路由器服務負責應用程序狀態和瀏覽器URL之間的同步。 實例化與同一瀏覽器URL交互的多個路由器服務會導致問題,因此,無論我們在應用程序中導入了多少個路由模塊,我們的應用程序中只有一個路由器服務實例非常重要。

    當我們導入使用RouterModule.forRoot()創建的路由模塊時,Angular將實例化路由器服務。 當我們導入使用RouterModule.forChild()創建的路由模塊時,Angular將不會實例化路由器服務。

    因此,對于附加的路由模塊,我們只能使用一次RouterModule.forRoot() ,并多次使用RouterModule.forChild() 。

    因為我們的應用程序只有一個路由模塊,所以我們使用RouterModule.forRoot() :

    imports: [RouterModule.forRoot(routes)]

    此外,我們還在exports屬性中指定了RouterModule :

    exports: [RouterModule]

    這確保了我們沒有明確導入RouterModule再次AppModule時AppModule進口AppRoutingModule 。

    現在我們有了AppRoutingModule ,我們需要將其導入到AppModule以啟用它。

    導入路由配置

    要將路由配置導入到應用程序中,我們必須將AppRoutingModule導入到主AppModule 。

    讓我們打開src/app/app.module.ts并將AppRoutingModule添加到AppModule的@NgModule元數據中的imports數組中:

    import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http';import { AppComponent } from './app.component'; import { TodoListComponent } from './todo-list/todo-list.component'; import { TodoListFooterComponent } from './todo-list-footer/todo-list-footer.component'; import { TodoListHeaderComponent } from './todo-list-header/todo-list-header.component'; import { TodoDataService } from './todo-data.service'; import { TodoListItemComponent } from './todo-list-item/todo-list-item.component'; import { ApiService } from './api.service'; import { AppRoutingModule } from './app-routing.module';@NgModule({declarations: [AppComponent,TodoListComponent,TodoListFooterComponent,TodoListHeaderComponent,TodoListItemComponent],imports: [AppRoutingModule,BrowserModule,FormsModule,HttpModule],providers: [TodoDataService, ApiService],bootstrap: [AppComponent] }) export class AppModule { }

    由于AppRoutingModule有RoutingModule在其上市exports財產,角將導入RoutingModule自動當我們導入AppRoutingModule ,所以我們沒有明確導入RouterModule再次(雖然這樣做不會造成任何傷害)。

    在嘗試在瀏覽器中進行更改之前,我們需要完成第三步也是最后一步。

    添加路由器插座

    盡管我們的應用程序現在具有路由配置,但是我們仍然需要告訴Angular Router它將實例化的組件放置在DOM中的位置。

    當我們的應用程序被引導時,Angular實例化AppComponent因為AppComponent的bootstrap屬性中列出了AppModule :

    @NgModule({// ...bootstrap: [AppComponent] }) export class AppModule { }

    為了告訴Angular Router可以在哪里放置組件,我們必須在AppComponentHTML模板中添加<router-outlet></router-outlet>元素。

    <router-outlet></router-outlet>元素告訴Angular Router可以在哪里實例化DOM中的組件。

    如果您熟悉AngularJS 1.x路由器和UI-Router ,可以考慮<router-outlet></router-outlet>替代ng-view和ui-view的Angular。

    如果沒有<router-outlet></router-outlet>元素,Angular Router將不知道組件的放置位置,并且僅AppComponent自己HTML。

    AppComponent當前顯示AppComponent列表。

    但是,我們現在不希望AppComponent顯示AppComponent列表,而是希望AppComponent包含<router-outlet></router-outlet>并告訴Angular Router實例化AppComponent內部的另一個組件以顯示AppComponent列表。

    為此,讓我們使用Angular CLI生成一個新組件TodosComponent :

    $ ng generate component Todos

    讓我們還將所有HTML從src/app/app.component.html移到src/app/todos/todos.component.html :

    <!-- src/app/todos/todos.component.html --> <section class="todoapp"><app-todo-list-header(add)="onAddTodo($event)"></app-todo-list-header><app-todo-list[todos]="todos"(toggleComplete)="onToggleTodoComplete($event)"(remove)="onRemoveTodo($event)"></app-todo-list><app-todo-list-footer[todos]="todos"></app-todo-list-footer> </section>

    讓我們還將所有邏輯從src/app/app.component.ts移到src/app/todos/todos.component.ts :

    /* src/app/todos/todos.component.ts */ import { Component, OnInit } from '@angular/core'; import { TodoDataService } from '../todo-data.service'; import { Todo } from '../todo';@Component({selector: 'app-todos',templateUrl: './todos.component.html',styleUrls: ['./todos.component.css'],providers: [TodoDataService] }) export class TodosComponent implements OnInit {todos: Todo[] = [];constructor(private todoDataService: TodoDataService) {}public ngOnInit() {this.todoDataService.getAllTodos().subscribe((todos) => {this.todos = todos;});}onAddTodo(todo) {this.todoDataService.addTodo(todo).subscribe((newTodo) => {this.todos = this.todos.concat(newTodo);});}onToggleTodoComplete(todo) {this.todoDataService.toggleTodoComplete(todo).subscribe((updatedTodo) => {todo = updatedTodo;});}onRemoveTodo(todo) {this.todoDataService.deleteTodoById(todo.id).subscribe((_) => {this.todos = this.todos.filter((t) => t.id !== todo.id);});} }

    現在,我們可以更換AppComponent的模板中src/app/app.component.html有:

    <router-outlet></router-outlet>

    我們也可以刪除所有過時代碼AppComponent的類src/app/app.component.ts :

    import { Component } from '@angular/core';@Component({selector: 'app-root',templateUrl: './app.component.html',styleUrls: ['./app.component.css'], }) export class AppComponent {}

    最后,我們更新src/app/app-routing.module.ts todos路由以實例化TodosComponent而不是AppComponent :

    const routes: Routes = [{path: '',redirectTo: 'todos',pathMatch: 'full'},{path: 'todos',component: TodosComponent} ];

    現在,當我們的應用程序啟動時,Angular實例化AppComponent并找到一個<router-outlet></router-outlet> ,Angular Router可以在其中實例化和激活組件。

    讓我們嘗試在瀏覽器中進行更改。

    通過運行以下命令啟動開發服務器和后端API:

    $ ng serve $ npm run json-server

    然后將瀏覽器導航到http://localhost:4200 。

    Angular Router會讀取路由器配置,并自動將瀏覽器重定向到http://localhost:4200/todos 。

    如果檢查頁面上的元素,您會看到TodosComponent不在<router-outlet></router-outlet>內部呈現,而是在其旁邊呈現:

    <app-root><!-- Angular Router finds router outlet --><router-outlet></router-outlet><!-- and places the component right next to it, NOT inside it --><app-todos></app-todos> </app-root>

    我們的應用程序現已啟用路由。 太棒了!

    添加通配符路由

    當您將瀏覽器導航到http://localhost:4200/unmatched-url并打開瀏覽器的開發人員工具時,您會注意到Angular Router將以下錯誤記錄到控制臺:

    Error: Cannot match any routes. URL Segment: 'unmatched-url'

    要優雅地處理不匹配的URL,我們需要做兩件事:

  • 創建PageNotFoundComponent (如果需要,可以命名不同)以顯示一條友好消息,即找不到所請求的頁面
  • 當沒有路由與請求的URL匹配時,告訴Angular Router顯示PageNotFoundComponent 。
  • 讓我們從使用Angular CLI生成PageNotFoundComponent開始:

    $ ng generate component PageNotFound

    然后在src/app/page-not-found/page-not-found.component.html編輯其模板:

    <p>We are sorry, the requested page could not be found.</p>

    接下來,我們使用**作為路徑添加通配符路由:

    const routes: Routes = [{path: '',redirectTo: 'todos',pathMatch: 'full'},{path: 'todos',component: AppComponent},{path: '**',component: PageNotFoundComponent} ];

    **匹配任何URL,包括子路徑。

    現在,如果將瀏覽器導航到http://localhost:4200/unmatched-url PageNotFoundComponent http://localhost:4200/unmatched-url , PageNotFoundComponent顯示PageNotFoundComponent 。

    請注意,通配符路由必須是我們路由配置中的最后一條路由,才能按預期工作。

    當Angular Router將請求URL與路由器配置進行匹配時,一旦找到第一個匹配項,它將立即停止處理。

    因此,如果我們將路線的順序更改為此:

    const routes: Routes = [{path: '',redirectTo: 'todos',pathMatch: 'full'},{path: '**',component: PageNotFoundComponent},{path: 'todos',component: AppComponent} ];

    然后todos將永遠不會達到和PageNotFoundComponent將顯示,因為通配符路線將首先匹配。

    我們已經做了很多工作,所以讓我們快速回顧一下到目前為止我們已經完成的工作:

    • 我們設置了角路由器
    • 我們為應用程序創建了路由配置
    • 我們重構AppComponent到TodosComponent
    • 我們在AppComponent的模板中添加了<router-outlet></router-outlet>
    • 我們添加了通配符路由,以正常處理不匹配的網址。

    接下來,我們將創建解析器以使用Angular Router從我們的后端API中獲取現有的待辦事項。

    使用Angular路由器解析數據

    在本系列的第3部分中,我們已經學習了如何使用Angular HTTP服務從后端API提取數據。

    當前,當我們將瀏覽器導航到todos URL時,會發生以下情況:

  • Angular Router匹配todos URL
  • Angular Router激活TodosComponent
  • Angular Router將TodosComponent放置在TodosComponent中的<router-outlet></router-outlet>旁邊
  • TodosComponent在瀏覽器中顯示,帶有一個空的todos數組
  • ngOnInit是從TodosComponent的ngOnInit處理程序中的API獲取的
  • 瀏覽器中的TodosComponent會使用從API獲取的TodosComponent進行更新。
  • 如果在步驟5中加載待辦事項需要三秒鐘,則在步驟6中顯示實際待辦事項之前,將向用戶顯示一個空的待辦事項列表三秒鐘。

    如果TodosComponent的模板中包含以下HTML:

    <div *ngIf="!todos.length">You currently do not have any todos yet. </div>

    那么在顯示實際待辦事項之前,用戶將看到此消息三秒鐘,這可能會完全誤導用戶并導致用戶在輸入實際數據之前先離開。

    我們可以在TodosComponent中添加一個加載器,以在加載數據時顯示一個微調TodosComponent ,但是有時我們可能無法控制實際的組件,例如,當我們使用第三方組件時。

    要解決此不良行為,我們需要進行以下操作:

  • Angular Router匹配todos URL
  • Angular Router從API獲取待辦事項
  • Angular Router激活TodosComponent
  • Angular Router將TodosComponent放置在TodosComponent中的<router-outlet></router-outlet>旁邊
  • TodosComponent顯示在瀏覽器中,并帶有從API提取的TodosComponent 。
  • 在這里,直到來自我們的API后端的數據可用時, TodosComponent顯示TodosComponent 。

    這正是解析器可以為我們做的。

    為了讓Angular Router在激活TodosComponent之前解析TodosComponent ,我們必須做兩件事:

  • 創建一個從API獲取TodosResolver
  • 在激活todos路由中的TodosComponent時,告訴Angular Router使用TodosResolver來獲取TodosComponent 。
  • 通過將解析器連接到todos路由,我們要求Angular Router在激活TodosComponent之前先解析數據。

    因此,讓我們創建一個解析器以獲取我們的待辦事項。

    創建TodosResolver

    Angular CLI沒有用于生成解析器的命令,因此讓我們手動創建一個新文件src/todos.resolver.ts并添加以下代碼:

    import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router'; import { Observable } from 'rxjs/Observable'; import { Todo } from './todo'; import { TodoDataService } from './todo-data.service';@Injectable() export class TodosResolver implements Resolve<Observable<Todo[]>> {constructor(private todoDataService: TodoDataService) {}public resolve(route: ActivatedRouteSnapshot,state: RouterStateSnapshot): Observable<Todo[]> {return this.todoDataService.getAllTodos();} }

    我們將解析器定義為實現Resolve接口的類。

    Resolve接口是可選的,但是讓我們的TypeScript IDE或編譯器通過要求我們實現resolve()方法來確保我們正確地實現了該類。

    當Angular Router需要使用解析器解析數據時,它將調用解析器的resolve()方法,并期望resolve()方法返回一個值,一個Promise或一個Observable。

    如果resolve()方法返回一個Promise或可觀察的Angular路由器將在激活路由的組件之前等待該Promise或可觀察的對象完成。

    當調用resolve()方法時,Angular Router可以方便地傳遞已激活的路由快照和路由器狀態快照,以使我們可以訪問數據(例如,路由參數或查詢參數),我們可能需要解析數據。

    TodosResolver的代碼非常簡潔,因為我們已經有一個TodoDataService來處理與API后端的所有通信。

    我們注入TodoDataService在構造和使用其getAllTodos()方法中獲取所有待辦事項resolve()方法。

    resolve方法返回類型為Todo[]的可觀察對象,因此Angular Router將等待可觀察對象完成,然后激活路由的組件。

    現在我們有了解析器,讓我們配置Angular Router來使用它。

    通過路由器解析待辦事項

    為了使Angular Router使用解析器,我們必須將其附加到路由配置中的路由上。

    讓我們打開src/app-routing.module.ts并將我們的TodosResolver添加到todos路由中:

    import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { PageNotFoundComponent } from './page-not-found/page-not-found.component'; import { TodosComponent } from './todos/todos.component'; import { TodosResolver } from './todos.resolver';const routes: Routes = [{path: '',redirectTo: 'todos',pathMatch: 'full'},{path: 'todos',component: TodosComponent,resolve: {todos: TodosResolver}},{path: '**',component: PageNotFoundComponent} ];@NgModule({imports: [RouterModule.forRoot(routes)],exports: [RouterModule],providers: [TodosResolver] }) export class AppRoutingModule { }

    我們導入TodosResolver :

    import { TodosResolver } from './todos.resolver';

    也將它添加為todos路線的解析器:

    {path: 'todos',component: TodosComponent,resolve: {todos: TodosResolver} }

    這告訴Angular Router使用TodosResolver解析數據,并將解析器的返回值指定為路由數據中的todos 。

    可以從ActivatedRoute或ActivatedRouteSnapshot訪問路線的數據,我們將在下一部分中看到它們。

    您可以使用路線的data屬性將靜態數據直接添加到路線的數據中:

    {path: 'todos',component: TodosComponent,data: {title: 'Example of static route data'} }

    您還可以使用在路由的resolve屬性中指定的解析器添加動態數據:

    resolve: {path: 'todos',component: TodosComponent,resolve: {todos: TodosResolver} }

    您也可以同時做兩個:

    resolve: {path: 'todos',component: TodosComponent,data: {title: 'Example of static route data'}resolve: {todos: TodosResolver} }

    一旦解析來自resolve屬性的解析器,它們的值就會與來自data屬性的靜態數據合并,并且所有數據都將用作路徑的數據。

    Angular Router使用Angular依賴注入來訪問解析器,因此我們必須確保將TodosResolver注冊到Angular的依賴注入系統中,方法是將其添加到AppRoutingModule的@NgModule元數據中的providers屬性中:

    @NgModule({imports: [RouterModule.forRoot(routes)],exports: [RouterModule],providers: [TodosResolver] }) export class AppRoutingModule { }

    當您將瀏覽器導航到http://localhost:4200 ,Angular Router現在:

  • 將URL從/重定向到/todos
  • 看到todos路由在resolve屬性中定義了TodosResolver
  • 從TodosResolver運行resolve()方法,等待結果并將結果分配給路線數據中的todos
  • 激活TodosComponent 。
  • 如果打開開發人員工具的“網絡”標簽,您會看到待辦事項現在已從API提取了兩次。 一次由Angular Router提供,一次由ngOnInit中的ngOnInit處理程序TodosComponent 。

    因此,Angular Router已經從API提取了TodosComponent ,但是TodosComponent仍然使用其自己的內部邏輯來加載待辦事項。

    在下一節中,我們將更新TodosComponent以使用Angular Router解析的數據。

    使用已解析的數據

    讓我們打開app/src/todos/todos.component.ts 。

    ngOnInit()處理程序當前直接從API獲取ngOnInit() :

    public ngOnInit() {this.todoDataService.getAllTodos().subscribe((todos) => {this.todos = todos;}); }

    現在,Angular Router使用TodosResolver來獲取TodosResolver ,我們想從路由數據而非API中獲取TodosComponent中的TodosComponent 。

    要訪問路線數據,我們必須從@angular/router導入ActivatedRoute :

    import { ActivatedRoute } from '@angular/router';

    并使用Angular依賴注入來獲取已激活路由的句柄:

    constructor(private todoDataService: TodoDataService,private route: ActivatedRoute ) { }

    最后,我們更新ngOnInit()處理程序,以從路線數據而非API獲取ngOnInit() :

    public ngOnInit() {this.route.data.map((data) => data['todos']).subscribe((todos) => {this.todos = todos;}); }

    ActivatedRoute將路由數據公開為可觀察的,因此我們的代碼幾乎不變。

    我們用this.route.data.map((data) => data['todos'])替換this.todoDataService.getAllTodos() ,其余所有代碼保持不變。

    如果將瀏覽器導航到localhost:4200并打開“網絡”標簽,您將不再看到兩個HTTP請求從API提取待辦事項。

    任務完成! 我們已成功將Angular Router集成到我們的應用程序中!

    在總結之前,讓我們運行單元測試:

    ng serve

    一個單元測試失敗:

    Executed 11 of 11 (1 FAILED) TodosComponent should create FAILED'app-todo-list-header' is not a known element

    當測試TodosComponent ,測試平臺不知道TodoListHeaderComponent ,因此Angular抱怨它不知道app-todo-list-header元素。

    要解決此錯誤,我們打開app/src/todos/todos.component.spec.ts并將NO_ERRORS_SCHEMA添加到TestBed選項中:

    beforeEach(async(() => {TestBed.configureTestingModule({declarations: [TodosComponent],schemas: [NO_ERRORS_SCHEMA]}).compileComponents(); }));

    現在,業力顯示另一個錯誤:

    Executed 11 of 11 (1 FAILED) TodosComponent should create FAILEDNo provider for ApiService!

    讓我們將必要的提供程序添加到測試平臺選項中:

    beforeEach(async(() => {TestBed.configureTestingModule({declarations: [TodosComponent],schemas: [NO_ERRORS_SCHEMA],providers: [TodoDataService,{provide: ApiService,useClass: ApiMockService}],}).compileComponents(); }));

    這再次引發另一個錯誤:

    Executed 11 of 11 (1 FAILED) TodosComponent should create FAILEDNo provider for ActivatedRoute!!

    讓我們為測試床選項添加一個更多的ActivatedRoute提供程序:

    beforeEach(async(() => {TestBed.configureTestingModule({declarations: [TodosComponent],schemas: [NO_ERRORS_SCHEMA],providers: [TodoDataService,{provide: ApiService,useClass: ApiMockService},{provide: ActivatedRoute,useValue: {data: Observable.of({todos: []})}}],}).compileComponents(); }));

    我們為ActivatedRoute的提供者分配了一個模擬對象,該對象包含一個可觀察的data屬性,以顯示todos的測試值。

    現在,單元測試成功通過:

    Executed 11 of 11 SUCCESS

    極好! 要將我們的應用程序部署到生產環境中,我們現在可以運行:

    ng build --aot --environment prod

    我們將生成的dist目錄上載到我們的托管服務器。 那有多甜?

    我們已經在本文中介紹了很多內容,所以讓我們回顧一下我們所學到的內容。

    摘要

    在第一篇文章中 ,我們學習了如何:

    • 使用Angular CLI初始化我們的Todo應用程序
    • 創建一個Todo類來代表單個Todo
    • 創建TodoDataService服務以創建,更新和刪除待辦事項
    • 使用AppComponent組件顯示用戶界面
    • 將我們的應用程序部署到GitHub頁面

    在第二篇文章中 ,我們重構了AppComponent ,將其大部分工作委托給:

    • TodoListComponent以顯示TodoListComponent列表
    • TodoListItemComponent以顯示單個待辦事項
    • 一個TodoListHeaderComponent來創建一個新的待辦事項
    • TodoListFooterComponent來顯示還剩下多少個TodoListFooterComponent 。

    在第三篇文章中 ,我們學習了如何:

    • 創建一個模擬REST API后端
    • 將API URL存儲為環境變量
    • 創建一個ApiService與REST API通信
    • 更新TodoDataService以使用新的ApiService
    • 更新AppComponent以處理異步API調用
    • 創建一個ApiMockService以避免在運行單元測試時進行真正的HTTP調用。

    在第四篇文章中,我們了解到:

    • 為什么應用程序可能需要路由
    • 什么是JavaScript路由器
    • 什么是Angular Router,它如何工作以及可以為您做什么
    • 如何為我們的應用程序設置Angular Router和配置路由
    • 如何告訴Angular Router在DOM中的何處放置組件
    • 如何妥善處理未知URL
    • 如何使用解析器讓Angular Router解析數據。

    這篇文章中的所有代碼都可以在GitHub上找到 。

    在第五部分中,我們將實現身份驗證以防止未經授權訪問我們的應用程序。

    因此,請繼續關注更多內容,并且與往常一樣,隨時在評論中留下您的想法和問題!

    推薦課程

    Angular和TypeScript在線課程 托德·格托 專家指導的針對個人和團隊的在線AngularJS,Angular和TypeScript培訓課程。 結帳時使用優惠券代碼“ SITEPOINT”可獲得25%的折扣

    翻譯自: https://www.sitepoint.com/component-routing-angular-router/

    angular復用路由組件

    總結

    以上是生活随笔為你收集整理的angular复用路由组件_Angular Router的组件路由简介的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。