[Angular學習紀錄] 路由機制
SPA(Single Page Application)的開發方式就是指透過一個 html 檔案來達成整個網站系統的任何操作,從頭到尾都不會離開此頁面,例如 Web Gmail 就是一個典型的 SPA 設計,回過頭來看一下 Angular 的基礎示範教學中也是使用 SPA 的方式,並透過屬性的判斷來決定使否載入某個 Template。
小型應用程式只有少數幾個頁面,使用此方式到還好,但假想一下有一個中大型應用程式有數十甚至數百個頁面需要切換,如果再像小型應用程式一樣透過屬性判斷的方式,後續整個程式碼可能會出現難以維護的情況,因此這種時候就需要運用 Angular 所提供的路由機制來處理此類的問題了。
什麼是路由? 簡單來說就是 Angular 會根據瀏覽器中的 URL,自動對應到要載入的視圖,這跟其它開發語言的路由,如 ASP.NET MVC 的概念是差不多的,差別在 Angular 透過路由機制來完成單一個網頁檔案切換視圖(SPA)的效果。
Angular 路由器是一個可選擇的外部 Angular NgModule,名叫RouterModule。 路由器包含了多種服務(RouterModule)、多種指令(RouterOutlet、RouterLink、RouterLinkActive)、 和一套配置(Routes),本文將說明如何建立 Angular 路由設定。
路由器設定的必要條件,必須確保 base href 的存在,因此請打開 index.html,確保head標籤內是否有,設定<base href="/">。
路由模塊,由於路由器預設是不存在的,因此必須在 app.module.ts 內 import RouterModule 建立預設路由,你可以直接寫在 module 內,但一般來說會建立路由就是因為程式數量較多,因此原則上都至少會拆出一個路由,並獨立出一個檔案,在這裡我們命名為 app-routing.module.ts。
app.module.ts 匯入路由語法參考如下,注意一下註解的部分是原本寫在 module 內的樣子,本範例會將它獨立一個新的檔案 app-routing.module.ts。
路由器定義是一個樹狀的結構,路由內部還可以包含子路由,這裡先介紹一下幾個常見的路由屬性。
router-outlet,路由插座,這樣的翻譯好像不太好理解,白話文就是要讓 Template 顯示的地方,以<router-outlet></router-outlet>呈現。
app-component.html 語法參考如下
1. 在 Template 內定義第二路由的位置及定義名稱(name="pop"),app-component.html 語法參考如下。
2. 在 routing 內指定第二路由的 outlet 為該定義的名稱,app-routing.module.ts語法參考如下。
3. 開啟第二路由的方式,app-component.html 語法參考如下。
4. 官網範例的第二路由的運用場景為開一個Pop視窗,因此若需隱藏該路由,layout2.component.ts 語法參考如下。
路由器的超連結路徑的寫法如下三種類型,請注意此處的超連結使用方式非傳統 href 的方式。
app-component.html 語法參考如下
app-component.ts 語法參考如下
還有多種取得路由傳遞的方式,這裡不一一說明,請自行參考範例檔內的語法。
layout3.component.ts 語法參考如下(後端取得帶參數的路由的參數值)
還有多種取得路由參數的方式,這裡不一一說明,請自行參考範例檔內的語法。
Angular路由器提供了routerLinkActive指令,可以用它來為匹配中的路由超連結添加一個CSS類別,因此我們需要定義該CSS的樣式,本文範例中選中的路由連結會變成紅底字。
上文中有提到,路由為一個樹狀結構,因此這裡的routerLinkActive一樣會套用選中節點和其所有父節點都會變成紅色,為了要解決該問題,必須在父節點內加上[routerLinkActiveOptions]="{exact : true}"。
app-component.html 語法參考如下
如果我們有更多特性區,它們的組件樹是這樣的:
子路由模組,以上這些說明是擷取自官網的說明和圖片,若看不懂的話,簡單的說明就是,一群處理相同事情的功能可以獨立出來成為一個模組,而且該模組可以擁有自己的路由設定和路由插座,下面簡單的介紹一下子路由的配置,若需詳細的說明可自行參閱官網。
1. 建立新的module和routing,這裡的範例為layout4,開啟console視窗,在專案目錄底下輸入 ng g m layout4 --routing,系統會協助我們建立 module 和 routing 兩個檔案(如下圖參考)。
2. 一樣在console視窗,建立兩個layout4A、layout4B,這兩個為稍後要當子路由模組的歸屬組件如下圖紅框處語法參考,此時 CLI 除了會幫我們產生檔案外,還會自動把組件一併加入layout4-module.ts當中。
3. 接下來就是定義子路由的樹狀結構了,可參考 layout4-routing.module.ts 內的語法定義,原則上路由的結構和上文提到結構都是類似的,只是這邊要特別留意一下children這個屬性定義該模組的子路由。
4. 再來設定一下子路由要顯示的布局,可參考 app-component.html 內的語法。
5. 最重要的記得將新加入的模塊 Layout4Module 加入 app.module.ts 當中。
# CanDeactivate
判斷是否允許離開路由,主要用來處理未保存的變更,本範例就簡單的示範登出前的詢問視窗就好了。
新增 can-deactivate-guard.service.ts 檔案,並實作 CanDeactivate 服務介面,並且在此指定要受到管控的類別為 AdminComponent,會在離開前跳出 confirm 視窗,照慣例,新增服務請記得將該類別一併加入 app.module.ts 內的 providers內。
設定路由參數,指定需要被管理的路由,加上 canDeactivate 屬性並傳入參數為一陣列,這裡就是剛剛建立的服務類別名稱 CanDeactivateGuard,請參閱 app-routing.module.ts ,部分語法如下參考。
# CanLoad
使否允許載入模塊,說明一下這個使用情境,會到上面惰性加載的部分,假設管理者模塊原本就是惰性加載,但在成功登入時,我們並不希望點選到該模塊就直接加載檔案的話,這時候就可以實作 Canload 介面來判斷是否允許加載,本範例就直接使用 layout4 來調整,必須在確認登入後,才會加載該模塊。
修改auth-guard.service.ts 路由服務,必且實作 CanLoad 介面,此範例為判斷是否登入,若有登入才加載該模塊,參考底下語法。
以上就是路由比較常用的功能,當然路由還有一些也有可能會使用到的特殊功能,就列出來讓大家參考,有需要可自行查詢,就不在逐一說明了。
本文範例請至Github下載。
參考網站
Angular官網(路由教學)
Angular官網(進階路由)
小型應用程式只有少數幾個頁面,使用此方式到還好,但假想一下有一個中大型應用程式有數十甚至數百個頁面需要切換,如果再像小型應用程式一樣透過屬性判斷的方式,後續整個程式碼可能會出現難以維護的情況,因此這種時候就需要運用 Angular 所提供的路由機制來處理此類的問題了。
什麼是路由? 簡單來說就是 Angular 會根據瀏覽器中的 URL,自動對應到要載入的視圖,這跟其它開發語言的路由,如 ASP.NET MVC 的概念是差不多的,差別在 Angular 透過路由機制來完成單一個網頁檔案切換視圖(SPA)的效果。
Angular 路由器是一個可選擇的外部 Angular NgModule,名叫RouterModule。 路由器包含了多種服務(RouterModule)、多種指令(RouterOutlet、RouterLink、RouterLinkActive)、 和一套配置(Routes),本文將說明如何建立 Angular 路由設定。
base href
路由器設定的必要條件,必須確保 base href 的存在,因此請打開 index.html,確保head標籤內是否有,設定<base href="/">。
<head>
<base href="/">
</head>
RouterModule
路由模塊,由於路由器預設是不存在的,因此必須在 app.module.ts 內 import RouterModule 建立預設路由,你可以直接寫在 module 內,但一般來說會建立路由就是因為程式數量較多,因此原則上都至少會拆出一個路由,並獨立出一個檔案,在這裡我們命名為 app-routing.module.ts。
app.module.ts 匯入路由語法參考如下,注意一下註解的部分是原本寫在 module 內的樣子,本範例會將它獨立一個新的檔案 app-routing.module.ts。
@NgModule({
imports: [
BrowserModule,
AppRoutingModule //底下的寫法與此方法相同,差別在將路由設定獨立出來而已
// RouterModule.forRoot([
// { path: '', redirectTo: '/layout1', pathMatch: 'full' },
// { path: 'layout1', component: Layout1Component }
// ])
]
bootstrap: [AppComponent]
})
export class AppModule { }
路由器定義是一個樹狀的結構,路由內部還可以包含子路由,這裡先介紹一下幾個常見的路由屬性。
- path : 定義名稱,路由機制會把URL內對應的此名稱轉換到對應的組件,注意path不能使用反斜線 ( / ) 開頭。
- 若為空為預設路由,若URL網址匹配為空,則會轉向到此處的設定。
- 之後若有接反斜線和分號 ( /: ),代表此路由必須帶入參數,否則會發生錯誤。
- 若為 ** ,萬用路由,所有匹配不符合的項目都會轉向此設定,須放在最後面。
- redirectTo : 轉向到另外一個定義的名稱,使用該屬性時一定要加上pathMatch。
- component : 路由名稱對應的組件名稱。
※ 請注意路由的轉址至多只會轉換一次,舉例來說 A 設定轉到 B,B 設定轉到 C,若從 A 進入只會轉到 B,並不會兩次轉址。
※ Angular 路由器的搜尋原則使用先匹配者優先的策略,若以匹配到符合則不會繼續進行底下的搜尋,這也解釋了為什麼官網中,預設路由總是放在最上方,而萬用路由一律放在所有路由的最底下。
※ 老舊的瀏覽器在當前位址的URL變化時總會往伺服器發送頁面請求,唯一的例外規則是:當這些變化位於“#”(被稱為“hash”)後面時不會發送。通過把應用內的路由URL拼接在#之後,路由器可以獲得這條“例外規則”帶來的優點,底下是兩種路由策略和說明。
app-routing.module.ts 語法參考如下※ Angular 路由器的搜尋原則使用先匹配者優先的策略,若以匹配到符合則不會繼續進行底下的搜尋,這也解釋了為什麼官網中,預設路由總是放在最上方,而萬用路由一律放在所有路由的最底下。
※ 老舊的瀏覽器在當前位址的URL變化時總會往伺服器發送頁面請求,唯一的例外規則是:當這些變化位於“#”(被稱為“hash”)後面時不會發送。通過把應用內的路由URL拼接在#之後,路由器可以獲得這條“例外規則”帶來的優點,底下是兩種路由策略和說明。
- PathLocationStrategy - 預設的策略,支持"HTML 5 pushState"風格。
- http://localhost:4200/layout1
- HashLocationStrategy - 支持"hash URL"風格。
- http://localhost:4200/#/layout1
const routes: Routes = [
{ path: '', redirectTo: '/layout1', pathMatch: 'full' },
{ path: 'layout1', component: Layout1Component },
{ path: 'layout2', component: Layout2Component },
{ path: 'layout3/:id', component: Layout3Component },
{ path: '**', redirectTo: '/layout1', pathMatch: 'full' }
];
@NgModule({
imports: [
RouterModule.forRoot(routes, {
useHash: false,
})],
exports: [RouterModule]
})
export class AppRoutingModule { }
RouterOutlet
router-outlet,路由插座,這樣的翻譯好像不太好理解,白話文就是要讓 Template 顯示的地方,以<router-outlet></router-outlet>呈現。
app-component.html 語法參考如下
<fieldset>
<legend>內容顯示區</legend>
<router-outlet></router-outlet>
</fieldset>
路由插座除了可以定義一個以外,一樣可以定義兩個路由器,但另外一個路由器則必須要指定名稱,詳細說明可以參閱官網,下面說明一下第二路由的使用方式。1. 在 Template 內定義第二路由的位置及定義名稱(name="pop"),app-component.html 語法參考如下。
<fieldset>
<legend>內容顯示區</legend>
<router-outlet></router-outlet>
</fieldset>
<fieldset>
<legend>第二路由內容顯示區</legend>
<router-outlet name="popup"></router-outlet>
</fieldset>
2. 在 routing 內指定第二路由的 outlet 為該定義的名稱,app-routing.module.ts語法參考如下。
{ path: 'layout2', component: Layout2Component, outlet: 'popup' } //增加oulet屬性,名稱為popup
3. 開啟第二路由的方式,app-component.html 語法參考如下。
<a [routerLink]="[{ outlets: { popup: ['layout2'] } }]">Layout2(顯示第二路由)</a>
4. 官網範例的第二路由的運用場景為開一個Pop視窗,因此若需隱藏該路由,layout2.component.ts 語法參考如下。
//關閉第二路由
onCloseRouter() {
this.router.navigate([{ outlets: { popup: null }}]);
}
RouterLink
路由器的超連結路徑的寫法如下三種類型,請注意此處的超連結使用方式非傳統 href 的方式。
- routerLink,在 Template 端寫死字串,適用於固定路由。
- [routerLink],在 Template 端透過屬性的傳遞,適用於動態路由。
- router.navigate,在 Component 程式端轉換,適用於動態路由或某種事件觸發。
app-component.html 語法參考如下
<a routerLink="/layout1">Layout1</a>
<a routerLink="/layout2">Layout2</a>
<a routerLink="/layout3/1983">Layout3(Template 死寫參數)</a>
<a [routerLink]="['layout3' , '2010']">Layout3(Template 屬性帶參數)</a>
<button (click)="goLayout3()">Layout3(Component 帶參數)</button>
還有多種取得路由傳遞的方式,這裡不一一說明,請自行參考範例檔內的語法。
export class AppComponent {
constructor(private route: ActivatedRoute, private router: Router) { }
goLayout3() {
this.router.navigate(['/layout3', '2013']);
}
}
還有多種取得路由參數的方式,這裡不一一說明,請自行參考範例檔內的語法。
constructor(private route: ActivatedRoute, private router: Router) { }
ngOnInit() {
//取得外部傳入的參數
this.route.params.subscribe(params => {
this.id = params["id"];
});
}
RouterLinkActive
Angular路由器提供了routerLinkActive指令,可以用它來為匹配中的路由超連結添加一個CSS類別,因此我們需要定義該CSS的樣式,本文範例中選中的路由連結會變成紅底字。
上文中有提到,路由為一個樹狀結構,因此這裡的routerLinkActive一樣會套用選中節點和其所有父節點都會變成紅色,為了要解決該問題,必須在父節點內加上[routerLinkActiveOptions]="{exact : true}"。
app-component.html 語法參考如下
<a routerLink="/layout1" routerLinkActive="active" [routerLinkActiveOptions]="{exact : true}">Layout1</a>
<a routerLink="/layout1/layout1-a" routerLinkActive="active">Layout1-A</a><br>
<a routerLink="/layout2" routerLinkActive="active">Layout2</a><br>
以上說明執行畫面如下參考
Child Routing Component
- 把每個特性放在自己的目錄中。
- 每個特性都有自己的Angular特性模塊。
- 每個特性區都有自己的根組件。
- 每個特性區的根組件中都有自己的路由出口及其子路由。
- 特性區的路由很少(或完全不)與其它特性區的路由交叉。
如果我們有更多特性區,它們的組件樹是這樣的:
子路由模組,以上這些說明是擷取自官網的說明和圖片,若看不懂的話,簡單的說明就是,一群處理相同事情的功能可以獨立出來成為一個模組,而且該模組可以擁有自己的路由設定和路由插座,下面簡單的介紹一下子路由的配置,若需詳細的說明可自行參閱官網。
1. 建立新的module和routing,這裡的範例為layout4,開啟console視窗,在專案目錄底下輸入 ng g m layout4 --routing,系統會協助我們建立 module 和 routing 兩個檔案(如下圖參考)。
2. 一樣在console視窗,建立兩個layout4A、layout4B,這兩個為稍後要當子路由模組的歸屬組件如下圖紅框處語法參考,此時 CLI 除了會幫我們產生檔案外,還會自動把組件一併加入layout4-module.ts當中。
3. 接下來就是定義子路由的樹狀結構了,可參考 layout4-routing.module.ts 內的語法定義,原則上路由的結構和上文提到結構都是類似的,只是這邊要特別留意一下children這個屬性定義該模組的子路由。
const routes: Routes = [
{
path: 'layout4',
component : Layout4Component,
children: [ //底下為子路由
{ path: 'layout4-a', component: Layout4AComponent }, //實際訪問路徑為 /layout4/layout4-a
{ path: 'layout4-b', component: Layout4BComponent } //實際訪問路徑為 /layout4/layout4-b
]
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class Layout4RoutingModule { }
4. 再來設定一下子路由要顯示的布局,可參考 app-component.html 內的語法。
<fieldset>
<legend>子路由示範區</legend>
<a routerLink="/layout4" routerLinkActive="active">Layout4</a>
<a routerLink="/layout4/layout4-a" routerLinkActive="active">Layout4-A</a>
<a routerLink="/layout4/layout4-b" routerLinkActive="active">Layout4-B</a>
</fieldset>
5. 最重要的記得將新加入的模塊 Layout4Module 加入 app.module.ts 當中。
@NgModule({
imports: [
BrowserModule,
Layout4Module,
AppRoutingModule
],
bootstrap: [AppComponent]
})
export class AppModule { }
6. 子路由範例示意如下圖Child Routing Lazy Loading
應用程式發展越來越大的時候,而有些模組並不是被大部分的人所使用的時候,可能就需要使用到惰性加載的功能,當使用者實際使用到該模組的時候 Angular 才將該模組的檔案加載到瀏覽器中使用,繼續上面的子路由的例子,只需要調整幾個步驟就可以達成惰性加載的功能,底下簡單的惰性加載的配置。
1. 把 Layout4RoutingModule 的路徑 layout4 清除改成空字串,參考layout4-routing.module.ts。
const routes: Routes = [
{
path: '', //清除layout4字串
component : Layout4Component,
children: [ //底下為子路由
{ path: 'layout4-a', component: Layout4AComponent }, //實際訪問路徑為 /layout4/layout4-a
{ path: 'layout4-b', component: Layout4BComponent } //實際訪問路徑為 /layout4/layout4-b
]
}
];
2. 在 AppRoutingModule 中增加一個 layout4的路由,並設定 loadChildren 屬性來加載 Layout4Module,參考app-routing.module.ts。
const routes: Routes = [
{ path: '', redirectTo: '/layout1', pathMatch: 'full' },
{ path: 'layout1', component: Layout1Component },
{ path: 'layout4', loadChildren : './layout4/layout4.module#Layout4Module' } //惰性加載
];
3. 務必清除 app.module.ts 中所有跟 Layout4Module 和其模組所有的引用關係,否則會造成延遲加載失效。
//import { Layout4Module } from './layout4/layout4.module'; //惰性加載需求,清除相依關係
@NgModule({
imports: [
BrowserModule,
//Layout4Module, //惰性加載需求,清除相依關係
AppRoutingModule
],
bootstrap: [AppComponent]
})
export class AppModule { }
4. 下圖紅框處為點選 Layout4 路由後才加載進來的檔案。
Route guards
路由守衛,Angular 為路由器提供了一個管理機制,讓使用者要進入、離開或者加載路由時,都可以被管理,目前 Angular 提供了以下幾個事件。
新增 auth-guard.service.ts 路由服務,必且實作 CanActivate 介面,此範例為判斷是否登入,若無登入則轉換到登入頁面,另外記住一下,該服務請一併加入 app.module.ts 內的 providers內。
設定路由參數,指定需要被管理的路由,加上 canActivate 屬性並傳入參數為一陣列,這裡就是剛剛建立的服務類別名稱 AuthGuard,請參閱 app-routing.module.ts ,部分語法如下參考。
接下來就是撰寫登入邏輯,實際運作後應該會發現,瀏覽到 /admin 路由時會轉跳到 /login 頁面,若成功登入後會再轉回 /admin,登入登出的寫法就不在這邊介紹了,有興趣的人可自行參閱 login.component.ts 和 admin.component.ts 兩個檔案。
- 用CanActivate來處理導航到某路由的情況。
- 用CanActivateChild處理導航到子路由的情況。
- 用CanDeactivate來處理從當前路由離開的情況。
- 用Resolve在路由啟動之前獲取路由資料。
- 用CanLoad來處理非同步導航到某特性模組的情況。
# CanActivate
要求取得進入路由的憑證,應用程式通常會根據訪問者來決定是否授予某個特性區的訪問權。 我們可以只對已認證過的用戶或具有特定角色的用戶授予訪問權,還可以阻止或限制用戶訪問權,直到用戶帳戶啟動為止。
新增 auth-guard.service.ts 路由服務,必且實作 CanActivate 介面,此範例為判斷是否登入,若無登入則轉換到登入頁面,另外記住一下,該服務請一併加入 app.module.ts 內的 providers內。
import { Injectable } from '@angular/core';
import { CanActivate, CanActivateChild, Router, RouterStateSnapshot, ActivatedRouteSnapshot } from '@angular/router';
import { User } from './user'; //模擬User登入類別
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private router: Router) { }
//使否允許存取路由
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
if (!User.IsLogin) { //未通過認證轉換到登入頁面
this.router.navigate(['/login']);
return false;
}
return true;
}
}
設定路由參數,指定需要被管理的路由,加上 canActivate 屬性並傳入參數為一陣列,這裡就是剛剛建立的服務類別名稱 AuthGuard,請參閱 app-routing.module.ts ,部分語法如下參考。
{ path: 'admin', component: AdminComponent, canActivate: [AuthGuard] }, //保護路由訪問權限
接下來就是撰寫登入邏輯,實際運作後應該會發現,瀏覽到 /admin 路由時會轉跳到 /login 頁面,若成功登入後會再轉回 /admin,登入登出的寫法就不在這邊介紹了,有興趣的人可自行參閱 login.component.ts 和 admin.component.ts 兩個檔案。
# CanActivateChild
要求取得進入子路由的憑證,功能和實作方式幾乎都跟 CanActivateChild 一樣,它的差別只是在保護子路由的存取權限,但若 Parent 路由已經有實作 CanActivate 就不需要再針對子路由進行設定了,就不多說明了,自行參考底下語法。
auth-guard.service.ts 參考如下
app-routing.module.ts 參考如下
auth-guard.service.ts 參考如下
import { Injectable } from '@angular/core';
import { CanActivate, CanActivateChild, Router, RouterStateSnapshot, ActivatedRouteSnapshot } from '@angular/router';
import { User } from './user'; //模擬User登入類別
@Injectable()
export class AuthGuard implements CanActivateChild {
constructor(private router: Router) { }
//允許訪問子路由
canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
return this.canActivate(childRoute, state);
}
}
app-routing.module.ts 參考如下
{
path: 'admin',
component: AdminComponent,
children: [
{
path: '',
canActivateChild: [AuthGuard], //保護子路由訪問權限
children: [
{ path: 'admin-a', component: AdminAComponent } //實際訪問路徑/admin/admin-a
]
}
]
},
# CanDeactivate
判斷是否允許離開路由,主要用來處理未保存的變更,本範例就簡單的示範登出前的詢問視窗就好了。
新增 can-deactivate-guard.service.ts 檔案,並實作 CanDeactivate 服務介面,並且在此指定要受到管控的類別為 AdminComponent,會在離開前跳出 confirm 視窗,照慣例,新增服務請記得將該類別一併加入 app.module.ts 內的 providers內。
import { Injectable } from '@angular/core';
import { CanDeactivate, Router, RouterStateSnapshot, ActivatedRouteSnapshot } from '@angular/router';
import { Observable } from 'rxjs';
import { AdminComponent } from './admin/admin.component';
@Injectable()
export class CanDeactivateGuard implements CanDeactivate<AdminComponent>
{
canDeactivate(component: AdminComponent,
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot) {
return confirm("確定要登出嗎?");
}
}
設定路由參數,指定需要被管理的路由,加上 canDeactivate 屬性並傳入參數為一陣列,這裡就是剛剛建立的服務類別名稱 CanDeactivateGuard,請參閱 app-routing.module.ts ,部分語法如下參考。
{ path: 'admin', component: AdminComponent, canDeactivate: [CanDeactivateGuard] }, //離開前的詢問判斷
# CanLoad
使否允許載入模塊,說明一下這個使用情境,會到上面惰性加載的部分,假設管理者模塊原本就是惰性加載,但在成功登入時,我們並不希望點選到該模塊就直接加載檔案的話,這時候就可以實作 Canload 介面來判斷是否允許加載,本範例就直接使用 layout4 來調整,必須在確認登入後,才會加載該模塊。
修改auth-guard.service.ts 路由服務,必且實作 CanLoad 介面,此範例為判斷是否登入,若有登入才加載該模塊,參考底下語法。
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate,
CanActivateChild, CanLoad, Router, Route, RouterStateSnapshot
} from '@angular/router';
import { User } from './user'; //模擬User登入類別
@Injectable()
export class AuthGuard implements CanLoad {
constructor(private router: Router) { }
//是否載入模塊
canLoad(route: Route): boolean {
return User.IsLogin;
}
}
設定路由參數,指定需要被管理的路由,加上 canDeactivate 屬性並傳入參數為一陣列,這裡就是剛剛建立的服務類別名稱 CanDeactivateGuard,請參閱 app-routing.module.ts ,部分語法如下參考。{ path: 'layout4', loadChildren: './layout4/layout4.module#Layout4Module', canLoad: [AuthGuard] }, //是否允許載入該模塊
以上就是路由比較常用的功能,當然路由還有一些也有可能會使用到的特殊功能,就列出來讓大家參考,有需要可自行查詢,就不在逐一說明了。
- 非同步載入 PreloadAllModules ,因為使用了惰性加載,但又希望可以在應用程式載入完畢後偷偷地繼續加載被設定惰性加載的模塊時使用。
- 自定義加載 preload,搭配惰性加載時使用。
- 路由守衛,用Resolve在路由啟動之前獲取路由資料。
本文範例請至Github下載。
參考網站
Angular官網(路由教學)
Angular官網(進階路由)
留言
張貼留言
您好,我是 Lawrence,這裡是我的開發筆記的網誌,如果你對我的文章有任何疑問或者有錯誤的話,歡迎留言讓我知道。