到目前為止我們都是在單一頁面撰寫 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
