[從 0 開始的 Angular 生活]No.39 實作一個 Angular Router 切換元件頁面(二)

前言

在上一篇的實作中,我們完成了一個最基礎的 Angular Router ,而本文將修改需求,將其擴充並實作出一個具有子路由功能的範例。

需求

延續上一份 ngRouteDemo 的範例,現在需求變更為:

  • 有前台 (front) 與後台 (back) 的區分
    • 前台就是一般人可以隨意瀏覽的部分
      • 裡面有 index 、 page1 、 page2 、 page3
    • 後台就是會套用路由守衛,要滿足條件才可以進入
      • 裡面有 index 、 page1 、 page2 、 page3

建立環境 - 區分前後台

先從區分前後台開始做起吧!

新增功能模組

新增兩個功能模組分別為:

  • front - 前台
  • back - 後台

新增功能模組,如:

1
ng g m front

執行完指令後 Angular CLI 會自動將我們新增的功能模組 import 至 AppModule 內。

此時 app.module 內容如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { FrontModule } from './front/front.module';
import { BackModule } from './back/back.module';

@NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
FrontModule,
BackModule,
AppRoutingModule,
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

特別注意此處 imports 陣列內的順序,父路由最後只會負責萬用字元路由與預設路由,因此應將其順序放於最後。

新增元件 & 搬運元件

我們新加入了兩個功能模組用來區分前後台,接著要建立前後台都有的 index 元件,目的是作為殼使用。

cd 進剛才建立的功能模組內,並新增元件,如:

1
ng g c index

最後將之前建立好的 Page1 、 Page2 、 Page3 元件搬進 front / back 功能模組內。

最後結構上會像是這樣

  • AppComponent - 父路由
    • front - 功能模組
      • index - 子路由
        • page1
        • page2
        • page3
    • back - 功能模組
      • index - 子路由
        • page1
        • page2
        • page3

別忘了要在建好的功能模組內, import 相關的元件進來,並且設置要 exports 的元件,因為最後配置父路由時會需要用到。

front.module

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { IndexComponent } from './index/index.component';
import { Page1Component } from './page1/page1.component';
import { Page2Component } from './page2/page2.component';
import { Page3Component } from './page3/page3.component';


@NgModule({
declarations: [
IndexComponent,
Page1Component,
Page2Component,
Page3Component
],
imports: [
CommonModule,
],
exports: [IndexComponent]
})
export class FrontModule { }

back.module 同 front.module 設置。

調整各個元件的 Template

front 功能模組 IndexComponent 的 Template

1
2
3
4
5
6
7
8
9
10
11
12
13
<h2>現在位於 front 元件,請點擊以下連結切換頁面</h2>
<ul>
<li>
<a routerLink="page1" routerLinkActive="active">page1</a>
</li>
<li>
<a routerLink="page2" routerLinkActive="active">page2</a>
</li>
<li>
<a routerLink="page3" routerLinkActive="active">page3</a>
</li>
</ul>
<router-outlet></router-outlet>

back 功能模組 IndexComponent 的 Template

1
2
3
4
5
6
7
8
9
10
11
12
13
<h2>現在位於 back 元件,請點擊以下連結切換頁面</h2>
<ul>
<li>
<a routerLink="page1" routerLinkActive="active">page1</a>
</li>
<li>
<a routerLink="page2" routerLinkActive="active">page2</a>
</li>
<li>
<a routerLink="page3" routerLinkActive="active">page3</a>
</li>
</ul>
<router-outlet></router-outlet>

AppComponent 的 Template

1
2
3
4
5
6
7
8
9
10
<h1>點擊以下連結切換元件</h1>
<ul>
<li>
<a routerLink="/front" routerLinkActive="active">前台</a>
</li>
<li>
<a routerLink="/back" routerLinkActive="active">後台(需驗證)</a>
</li>
</ul>
<router-outlet></router-outlet>

替功能模組設置子路由

複製 app-routing.module 並且貼進 front 功能模組內,重新命名為 front-routing.module

修改 front.module ,將剛才新增的路由設定檔引入,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { IndexComponent } from './index/index.component';
import { Page1Component } from './page1/page1.component';
import { Page2Component } from './page2/page2.component';
import { Page3Component } from './page3/page3.component';
import { FrontRoutingModule } from './front-routing.module';


@NgModule({
declarations: [
IndexComponent,
Page1Component,
Page2Component,
Page3Component
],
imports: [
CommonModule,
FrontRoutingModule
],
exports: [IndexComponent]
})
export class FrontModule { }

修改 front-routing.module

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { IndexComponent} from './index/index.component';
import { Page1Component } from './page1/page1.component';
import { Page2Component } from './page2/page2.component';
import { Page3Component } from './page3/page3.component';

const routes: Routes = [
{
path: 'front',
component: IndexComponent,
children: [
{
path: 'page1',
component: Page1Component,
},
{
path: 'page2',
component: Page2Component,
},
{
path: 'page3',
component: Page3Component,
}
],
},
];

@NgModule({
imports: [
RouterModule.forRoot(routes, { enableTracing: true })
],
exports: [RouterModule]
})
export class FrontRoutingModule { }

這部分 back 功能模組同 front 功能模組配置。

修改 app-routing.module 配置

配置完功能模組的子路由後,最後只需要微調一下這邊就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { IndexComponent } from './front/index/index.component';

const routes: Routes = [
{ path: '', redirectTo: '/front', pathMatch: 'full' },
{ path: '**', component: IndexComponent },
];

@NgModule({
imports: [
RouterModule.forRoot(routes, { enableTracing: true })
],
exports: [RouterModule]
})
export class AppRoutingModule { }

這裡 import front 功能模組內的 IndexComponent 元件,因為我希望當使用者胡亂輸入時會顯示這個元件。

測試看看

預設狀態

胡亂輸入時

切換到後台的狀態

處於前台且 page1 的狀態

小結

本來以為這部分應該不會太複雜,但在不熟 Angular 的情況下我還是搞了蠻久的。

當初預計這一篇要一起實作路由守衛的部分,看來只能下一篇了,不然篇幅太長囉。

0%