第 26 型 - 路由 (Router)

利用 Angualr 框架开发单一应用程序 (Single-Page Application, SPA) 时,会利用路由机制实作页面之间的切换。接下来几篇,会利用 Angular 路由机制来实作待办事项页面的切换。

前置作业

为了实作需求,利用 Angular CLI 建立一待办事项页面,由於此页面会利用路由机制来载入元件,因此在终端机中执行 ng g c task/task-page --skip-selector 指令,以取消元件选择器的设定,并将 app.component.html 中的页面程序移至 task-page.component.html

<app-page-container>
  <app-page-title pageTitle="待办事项清单"></app-page-title>
  <app-task-list></app-task-list>
</app-page-container>

因为 TaskPageComponent 主要职责是待办事项的清单显示,所以上面程序也移除了待办事项表单的标签;又由於此时会使用到 <app-page-container> 标签,因此还需要在 TaskModule 中汇入 UiModule 模组。

透过路由设定显示首页页面

实作之前先利用 Angular CLI 在 AppModule 模组下建立作为首页的页面 - MainPage;而在 app.component.html 中,会使用 <router-outlet> 元件来定义页面所需要显示的位置。

<router-outlet></router-outlet>

接着,在 app-routing.module.ts 来定义路由,此会是一 Routes 型别的物件阵列,定义网址路径与元件之间的关系。例如,可以定义在 main 路径时载入 MainPageComponent。

const routes: Routes = [
  { path: 'main', component: MainPageComponent },
];

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

依上面路径定义方式,可以在浏览器中输入 http://localhost:4200/main 网址来载入页面,Angular 会从 '/' 後面的路径与路由定义进行比较,进而载入对象的页面元件,或抛出找不到路由的例外讯息。

MainPage

在路由定义中,除了定义路径与元件之间,还可以利用 redirectTo 属性定义在特定路径下转址到其他路径中,例如,若要在载入 http://localhost:4200/ 时也载入 MainPageComponent 页面,就可以加入下面路径定义。

const routes: Routes = [
  { path: '', pathMatch: 'full', redirectTo: 'main' },
  { path: 'main', component: MainPageComponent },
];

利用 routerLink 指令实作页面切换

在一般的网页中,会利用 <a> 标签的 href 属性来切换页面,而在 Angular 应用程序中,则会使用 routerLink 指令来进行页面的切换。

因此,可以先在 app-routing.module.ts 中加入待办事项页面的路由定义,并在 app.component.html 加入页面导览列,在此导览列利用 routerLink 指令来设定要切换的页面,此指令可以接受字串或阵列。

const routes: Routes = [
  { path: '', pathMatch: 'full', redirectTo: 'main' },
  { path: 'main', component: MainPageComponent },
  { path: 'task-list', component: TaskPageComponent },
];
<nav>
  <a [routerLink]="['main']">首页</a>
  <a [routerLink]="'task-list'">待办事项</a>
</nav>
<router-outlet></router-outlet>

同样式,在 app.component.css 中加入导览列样式。

nav {
  padding: 10px;
}

nav a {
  margin-right: 10px;
  border: solid 1px #999;
  display: inline-block;
  font-size: 12pt;
  padding: 10px;
  min-width: 80px;
  text-align: center;
}

nav a:link,
nav a:visited,
nav a:hover,
nav a:active {
  color: black;
  text-decoration: none;
}

nav a.active {
  background-color: green;
  color: white;
}

nav

Angular 也提供了 routerLinkActive 指令来指定的样式类型名称,让导览器的显示会依当下路由路径套用不同样式。

<nav>
  <a [routerLink]="['main']" routerLinkActive="active">首页</a>
  <a [routerLink]="'task-list'" routerLinkActive="active">待办事项</a>
</nav>
<router-outlet></router-outlet>

active

利用 Router 服务切换页面

除了利用 routerLink 设定要前往的页面路径外,Angular 还提供了 Router 服务元件来设定路由的切换。首先,在 app-routing.module.ts 中再加入待办事项表单的路由设定。

const routes: Routes = [
  { path: '', pathMatch: 'full', redirectTo: 'main' },
  { path: 'main', component: MainPageComponent },
  { path: 'task-list', component: TaskPageComponent },
  { path: 'task-form', component: TaskFormComponent },
];

接着,在 task-list.component.html 加入新增按钮,让使用者可以透过此按钮切换至待办事项的表单页面中,并在 task-list.component.css 加入所需的样式。

<div class="toolbar">
  <button type="button" (click)="onAdd()">新增</button>
</div>
<form class="search" #form="ngForm" (submit)="onSearch(form)"></form>

最後,在 task-list.component.ts 中注入 Router 服务,并利用此服务元件的 navigate() 方法来切换至表单页面,此方法会传入路径的阵列;或者是利用 navigateByUrl() 方法传入路径字串来切换。

export class TaskListComponent implements OnInit {
  constructor(private router: Router, private taskService: TaskRemoteService) {}

  onAdd(): void {
    this.router.navigate(['task-form']);
    // this.router.navigateByUrl('/task-form');
  }
}

结论

这一篇利用 Angular 的路由机制,来实作待办事项清单与表单的页面切换;而下一篇则将会实作编辑按钮功能,来了解如何利用路由机制传递资料。


<<:  Day26影片教学:Azure小白如何使用Azure Container Registry异地复写建立多份Container Image

>>:  回头看结构行为合一这回事

DAY 23 - 四足战车 (4)

大家好~ 我是五岁~~ 今天来继续画四足车车~~ 接续昨天的草稿图,因为没有要重新描绘一次线稿,所以...

Day 21: 压力测试Jmeter

系统上线以前,如果我们没有去挑战一个系统的极限,我们永远不知道该系统最高可以有多少的可靠度,压力测试...

DigitalOcean VPS – Premium Droplets 主机测试和跑分,廉价和高效的网站主机

Cloudways 最近推出 DigitalOcean Premium Droplets 的新选择...

Day 29 QuickSight 连接 Redshift - Part 2

在设定完相关的环境参数後,可以开始设定 Redshift 的连接 一样先到 QuickSight 的...

[Day11] 智慧指标

老实说我还真的想不到要写啥了,有关基础语法,真的很难想欸QQ 拜托来个人给我点想法吧 QQQQQQQ...