前言
今天是進入公司的第三天,為了能盡快投入專案與成為團隊可用的戰力,我正在努力啃官方文件學習 Angular 的知識,所以這一篇文章主要是記錄我如何閱讀官方文件後,實作這個非常基本的、帶導航的網頁應用。
需求
需求大概是這樣的:
- 開一個新的 Angular 專案,並且一開始選擇加入 Router 功能
- 根元件是 AppComponent ,然後下方有三個子元件分別是
- page1
- page2
- page3
- 可以在 AppComponent 內點擊連結切換到這三個頁面
- 根元件是 AppComponent ,然後下方有三個子元件分別是
參考文件:
建立環境
輸入 ng new ngRouterDemo
建立新專案,並直接選擇要使用 Router 。
觀察檔案結構
這次選擇加入 Router 後,發現 app 資料夾內多了 app-routing.module.ts
1 | import { NgModule } from '@angular/core'; |
然後 app.module.ts
中也把 app-routing.module.ts
這隻檔案給引入了。
1 | import { BrowserModule } from '@angular/platform-browser'; |
對照一下有無加入 Router 的部分
除此之外就是 app 資料夾內多了 app-routing.module.ts
這隻檔案。
運行結果
沒有什麼明顯的變化。
分別建立三個元件
輸入指令建立本次範例用的元件
- page1
- page2
- page3
如 ng g c page1
配置路由
因為是選擇使用 Router 的模式,所以 Angular CLI 預設幫我們加入了 router-outlet
標籤,這代表路由切換後的畫面都會在這個標籤裡面呈現。
以下引用自官方說明:
RouterOutlet 是一個來自路由模組中的指令,它的用法類似於元件。 它扮演一個佔位符的角色,用於在範本中標出一個位置,路由器將會把要顯示在這個出口處的元件顯示在這裡。
有了這份配置,當本應用在瀏覽器中的 URL 變為 /heroes 時,路由器就會匹配到 path 為 heroes 的 Route,並在宿主檢視中的 RouterOutlet 之後顯示 HeroListComponent 元件。
加入 RouterLink 連結
因為要點擊連結後透過路由配置切換到該元件,所以必須先設置路由器連結 (Router links):
對 Appcomponent 進行 Template 上的調整
1 | <h1>點擊以下連結切換元件</h1> |
- RouterLink
- a 標籤上的 RouterLink 指令讓路由器得以控制這個 a 元素,這裡的導航路徑是固定的,因此可以把一個字串賦給 routerLink(”一次性”繫結)。
- 這後面接的就是實際上網址列顯示的路徑
- RouterLinkActive
- 在每個 a 標籤上,你會看到一個
RouterLinkActive
的屬性繫結,像是routerLinkActive="..."
- 等號右邊可以填入包含一些用空格分隔的 CSS 類名,當這個連結啟用時,路由器將會把它們加上去
- 並在處於非活動狀態時移除
- 在每個 a 標籤上,你會看到一個
為了方便辨識效果,所以也加入 .active 的樣式吧
1 | .active{ |
這邊要注意的是 CSS 樣式要寫在 Appcomponent 內。
註冊路由器與路由定義
要使用路由的話,必須要把要使用的元件 import 進來,並且在 routes
陣列內配置它們,陣列內傳入一個物件,而物件內可以傳入參數:
- path - 切換到這個元件的路徑
- component - 切換的元件名稱
1 | import { NgModule } from '@angular/core'; |
當我們定義好路由陣列 routes 並把它傳給 RouterModule.forRoot() 方法後:
- 它會返回一個模組,其中包含配置好的 Router 服務提供商,以及路由庫所需的其它提供商。
一旦啟動了應用 Router 就會根據當前的瀏覽器 URL 進行首次導航。
存檔,試著運行看看。
這樣基礎的 Angular 路由範例就完成了!
而因為我們有在 RouterModule.forRoot() 把 enableTracing
打開,所以當切換路由時時可以看到一些額外訊息:
設置萬用字元與預設路由
雖然我們基礎的範例完成了但還不夠好,因為:
- 如果在網址列隨意輸入會跳出錯誤
- 而使用者是這麼白目
- 需要設定一組預設路由,也就是使用者初次進入網頁時會顯示的畫面
設置萬用字元
新增一個萬用字元路由來攔截所有無效的 URL 並處理它們。 萬用字元路由的 path 是兩個星號(**),它會匹配任何 URL。 當路由器匹配不上以前定義的那些路由時,它就會選擇這個路由。
萬用字元路由可以導航到自訂的 “404 Not Found” 元件,也可以重定向到一個現有路由。
特別要注意的是:
路由器使用先匹配者優先的策略來選擇路由,萬用字元路由是路由配置中最沒有特定性的那個,因此務必確保它是配置中的最後一個路由。
因此修改 app-routing.module
1 | import { NgModule } from '@angular/core'; |
像這樣,永遠確保萬用字元在最後一組路由就可以了,而且也不會跳錯誤。
設置預設路由
與設置萬用字元時差不多,由於路由是有順序性的,因此應該其放在萬用字元路由的前一個。
1 | import { NgModule } from '@angular/core'; |
為了方便辨識,我將預設路由設置為 page2
,也就是預期當使用者初次進入網站時會看到這個畫面。
重定向路由需要一個 pathMatch 屬性,來告訴路由器如何用 URL 去匹配路由的路徑,否則路由器就會報錯。
在本範例中路由器應該只有在完整的 URL 等於 ‘’ 時才選擇 Page2Component 元件,因此要把
pathMatch
設定為 ‘full’。
可以觀察下方的 log ,發現一開始如果網址都沒輸入時,會自動跳轉到
page2
順序錯誤的場合
前面提到路由器使用先匹配者優先的策略來選擇路由,所以順序很重要,如果把萬用字元的順序稍微挪動,如:
1 | const routes: Routes = [ |
因為匹配到的路由會變成萬用字元的路由,因此就不會跳轉到 page2
了。
小結
透過實作這個非常基本的、帶導航的網頁應用學到了如何:
- 載入路由庫
- 在根元件的 Template 中新增一個導覽列,導覽列中有一些 A 標籤、routerLink 指令和 routerLinkActive 指令
- 在根元件的 Template 中新增一個 router-outlet 指令,頁面將會被顯示在那裡
- 用 RouterModule.forRoot 配置路由器模組
- 使用萬用字元路由來處理無效路由
當應用在空路徑下啟動時,導航到預設路由
之後會嘗試實作路由守衛的部分。