本文同步發佈於:Claire's BLOG
Routing
意指路由器,也就是由一個路由器來決定現在要顯示的頁面是什麼
在套用Routing
時,會有下列的實踐流程
Routing
來決定現在要顯示什麼畫面)在Angular裡,最佳做法是將載入和設定Routing放在一個top-level的模組內,並於AppModule內來import所有的路由資訊。
按照慣例,模組AppRoutingModule
和app-routing.module.ts
會放在src/app
裡
Angular的Routing 產生的虛擬 URL,並不是真的存在於檔案系統裡,因此需要伺服器能夠支援,否則重新整理時會出現404 not found。
透過下列CLI的指令來新增一個Routing
ng generate module app-routing --flat --module=app
--flat
的意思是將產出文件放在src/app
裡,而非自己一個資料夾--module=app
則是告知CLI註冊這個Routing
在AppModule
的imports裡
新產生的src/app/app-routing.module.ts
檔案內容如下:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
@NgModule({
imports: [
CommonModule
],
declarations: []
})
export class AppRoutingModule { }
一般我們不會在Routing
裡宣告元件,因此可以將@NgModule.declarations
及CommonModule
的宣告刪除
通常我們會使用Routes
與RouterModule
來實做Routing
,修改後的檔案如下:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
@NgModule({
exports: [ RouterModule ]
})
export class AppRoutingModule {}
此時我們來設定不同路徑要導向的位置,如下面的程式碼
import { HeroesComponent } from './heroes/heroes.component';
const routes: Routes = [
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },
{ path: 'heroes', component: HeroesComponent },
{ path: 'detail/:id', component: HeroDetailComponent }
];
上述程式碼代表在網址為http://localhost/heroes
時,會在標籤內顯示HeroesComponent
這元件的內容。
另外,也要設定當伺服器剛運行時(http://localhost/
),要顯示的模組。
就是上面path: ''的這個設定。
設定完Router的map後,將之設定進RouterModule.forRoot()
裡
然後再將這整個Router功能設定為可以被export,之後便可以在app.module裡import這個Router
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { DashboardComponent } from './dashboard/dashboard.component';
import { HeroesComponent } from './heroes/heroes.component';
import { HeroDetailComponent } from './hero-detail/hero-detail.component';
const routes: Routes = [
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },
{ path: 'dashboard', component: DashboardComponent },
{ path: 'detail/:id', component: HeroDetailComponent },
{ path: 'heroes', component: HeroesComponent }
];
@NgModule({
imports: [ RouterModule.forRoot(routes) ],
exports: [ RouterModule ]
})
export class AppRoutingModule {}
而detail/:id
裡的:id
可於HeroDetailComponent
裡去取得,來做進一步更詳細的資料顯示
取得方法如下:
ngOnInit(): void {
this.getHero();
}
getHero(): void {
const id = +this.route.snapshot.paramMap.get('id');//用route.snapshot.paramMap.get取得Routing時傳入的變數
this.heroService.getHero(id)
.subscribe(hero => this.hero = hero);
}
我們可以發現,例子中不同的path為所傳入的參數不同,它們代表不同的意義,可以更多元化的設定Routing的功能。
Routes可傳入的參數有下面這些
interface Route {
path?: string //瀏覽器上方的網址列的字串
pathMatch?: string //當導航至此網址時要顯示的元件
matcher?: UrlMatcher //網址列過濾器
component?: Type redirectTo?: string //要轉址到那邊
outlet?: string
canActivate?: any[]
canActivateChild?: any[]
canDeactivate?: any[]
canLoad?: any[]
data?: Data //要傳入元件裡的資料
resolve?: ResolveData
children?: Routes
loadChildren?: LoadChildren
runGuardsAndResolvers?: RunGuardsAndResolvers
}
在這邊可看一下APP_BASE_HREF
的設定方式
如果沒有設定,會跑出錯誤訊息如下:
另一個簡單的方式則是在index.html增加下面這行,也可以解決這個錯誤
<base href="/">
在src/app/app.component.html
中增加這個導航功能
<h1>{{title}}</h1>
<router-outlet></router-outlet>
修改src/app/app.component.html
如下:
<h1>{{title}}</h1>
<nav>
<a routerLink="/heroes">Heroes</a>
</nav>
<router-outlet></router-outlet>
如果要回上一頁則使用
goBack(): void {
this.location.back();
}
這篇文章的範例檔案可由此觀看: live example / download example。