到目前為止我們都是在單一頁面撰寫 Angular,今天我們用 Angular 的 Routing 機制,來完成多個頁面的切換。
首先我們先整理一下很混亂的程式碼,我想要的結構長這樣:
先把 app.component.html
給清空,將原本的範本首頁程式碼移到 homepage.component.html
。
那麼我先加入一個 Component 叫 Navigation Bar,就是我們常在網頁看到的導航列。我在 W3C 找到這樣的一個範例,並且套用他。W3C Example
// app.component.html
<app-navigation-bar></app-navigation-bar>
我想用登入狀態來切換要顯示的導航按鈕,用 ngIf 將標籤包住,相信大家還不陌生。記得在 navigation-bar.component
宣告成員變數 islogin
:
// navigation-bar.component.html
<ul>
<li><a href="/home">Home</a></li>
<ng-container *ngIf="!islogin">
<li><a href="/register">Register</a></li>
<li><a href="/login">Login</a></li>
</ng-container>
<ng-container *ngIf="islogin">
<li><a href="/chart">Chart</a></li>
<li><a href="/logout">Logout</a></li>
</ng-container>
</ul>
在 <a>
標籤裡 定義好各 href
要導向的位址。複習一下,這個位置會參考 index.html
的 <base href="/">
,即會被導到 http://localhost:4200/login
、http://localhost:4200/logout
等位址。
navigation-bar.component.css
的部分有點長,我就不放了,請參考上面的 W3C Example,裡面有更詳細的內容。
(您獲得了一條導航列!)
Angular 建立範本專案時,會詢問要不要建立 RoutingModule
,選 y 的話就會建立一個 app-routing.module.ts
。
由於我們在建立專案時沒有加入 RoutingModule
,所以現在要手動建立他。我們遵循 Angular,名字固定叫 app-routing
比較好:
ng g m app-routing --flat
然後把這個 module 的程式碼換成下面這段,這是 Angular 的範本程式碼:
// app-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
const routes: Routes = [];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
routes
是一個 Route
的陣列,裡面放我們等等要定義的路由資訊。
import: [RouterModule.forRoot(routes)]
,這邊將 routes
資訊載入到 RouterModule
,由於我們這個 module 是要匯出給 AppModule
使用,而 AppModule
是 root module,所以要用forRoot()
,如果是 root module 以外的 module 就用 forChild()
。
然後在 app.module.ts
匯入:
// app.module.ts
import { AppRoutingModule } from './app-routing.module';
...
imports: [
BrowserModule,
AppRoutingModule,
...
],
...
你也可以把這些程式碼寫在 AppModule
中,不過我覺得這樣分成兩個檔案比較乾淨。
接下來要定義路由資訊了,回到剛剛 AppRoutingModule
的 const routes: Routes = []
,我們添加以下兩筆 Route 物件:
// app-routing.module.ts
const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'home', component: HomepageComponent},
];
第一筆的 path: ''
就是相對於 <base href="/">
的根位置: http://localhost:4200/
。
redirectTo
設定要導向哪個 URL,這邊是導向 /home
這個位址。
pathMatch: 'full'
是設定輸入的網址要與 path
設定的位址一樣,才會做 redirect。所以我一定要輸入http://localhost:4200/
,才會正確導到 http://localhost:4200/home
。
而如果是設定 pathMatch: 'prefix'
的話,只要 url 符合 path
的 prefix,就會幫忙導向。而這邊的 path
是空字串,所以設定 prefix 的話,無論 url 後面輸入甚麼,都會導到 /home
底下。
第二筆的 component
即是指,如果我在 http://localhost:4200/home
,要顯示 HomepageComponent
這個元件。
顯示顯示,到底要顯示在哪裡呢?
我們要使用 <router-outlet></router-outlet>
這個標籤。它被稱作路由插座,當進入我們的網頁時,Angular 的 Router 會查看我們配置的 routes
陣列,並在這邊顯示對應的 Component。
所以要在 app.component.html
加入 <router-outlet></router-outlet>
:
// app.component.html
<app-navigation-bar></app-navigation-bar>
<router-outlet></router-outlet>
此時我進入 http://localhost:4200/
,就會被 redirect 到 http://localhost:4200/home
,這時 Router 就會解析到 /home
這個位址,顯示 HomepageComponent
。
畫面如下:http://localhost:4200/home