Angular-第10課-路由重新導向與返回

Vincent Zheng
新手工程師的程式教室
9 min readDec 16, 2018

Yahoo奇摩以前推出「Yahoo奇摩部落格」和「無名小站」這兩項部落格平台,如今都已停止服務。現在若把部落格的相關網址直接貼到瀏覽器上並前往,我們最後會跑到Yahoo奇摩的首頁。

以上就是「重新導向」的機制。另外本課也會學習如何在網頁畫面中,直接返回到上一個瀏覽的地方。

課程關鍵字:#重新導向(redirect) #Location

一、重新導向

在應用程式初次啟動時,瀏覽器的網址均為「localhost:4200」。這個便是網站的「根路徑」,以「空字串」來表示。目前這裡的畫面只看得到標題和一個超連結。若希望前往這個URL時能夠自動移轉至其他網址,就需要利用「重新導向」的功能。

為了練習這個功能,我們先建立一個名為dashboard的新組件:

ng generate component dashboard

本節有蠻大篇幅是html、ts與css檔的範例內容,這裡就不解說之前課程已提過的細節,直接複製貼上即可,有興趣者再自行研究。若只是想知道重新導向如何實作,請參考本節後半部。

接下來請將相關檔案直接編輯為如下:

dashboard.component.html

<h3>Top Heroes</h3>
<div class="grid grid-pad">
<a *ngFor="let hero of heroes" class="col-1-4"
routerLink="/detail/{{hero.id}}">
<div class="module hero">
<h4>{{hero.name}}</h4>
</div>
</a>
</div>

dashboard.component.ts

import { Component, OnInit } from '@angular/core';
import { Hero } from '../hero';
import { HeroService } from '../hero.service';
@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: [ './dashboard.component.css' ]
})
export class DashboardComponent implements OnInit {
heroes: Hero[] = [];
constructor(private heroService: HeroService) { }ngOnInit() {
this.getHeroes();
}
getHeroes(): void {
this.heroService.getHeroes()
.subscribe(heroes => this.heroes = heroes.slice(1, 5));
}
}

dashboard.component.css

/* DashboardComponent's private CSS styles */
[class*='col-'] {
float: left;
padding-right: 20px;
padding-bottom: 20px;
}
[class*='col-']:last-of-type {
padding-right: 0;
}
a {
text-decoration: none;
}
*, *:after, *:before {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
h3 {
text-align: center; margin-bottom: 0;
}
h4 {
position: relative;
}
.grid {
margin: 0;
}
.col-1-4 {
width: 25%;
}
.module {
padding: 20px;
text-align: center;
color: #eee;
max-height: 120px;
min-width: 120px;
background-color: #607d8b;
border-radius: 2px;
}
.module:hover {
background-color: #eee;
cursor: pointer;
color: #607d8b;
}
.grid-pad {
padding: 10px 0;
}
.grid-pad > [class*='col-']:last-of-type {
padding-right: 20px;
}
@media (max-width: 600px) {
.module {
font-size: 10px;
max-height: 75px; }
}
@media (max-width: 1024px) {
.grid {
margin: 0;
}
.module {
min-width: 60px;
}
}

基本上這個組件的設計和HeroesComponent很像。只不過它改為呈現類似儀表板的畫面,上面列出4個顯眼的hero物件。此外,在ts檔中透過HeroService取得hero陣列後,特別使用了「slice」方法來擷取陣列第2~5個元素,作為顯示之用。

Dashboard組件完成後,請將它加入路由模組的陣列中,這樣就能先在瀏覽器的URL加上「/dashboard」看到這個畫面:

{ path: 'dashboard', component: DashboardComponent }
dashboard組件的畫面

然而本節的重點是「重新導向」,若希望在使用者前往「根路徑」的URL時,自動被導向到這個URL,請在剛剛的陣列中再加入一個Routes物件:

{ path: '', redirectTo: '/dashboard', pathMatch: 'full' }

這個項目與先前不太一樣。redirect屬性是重新導向的目的路徑。
至於pathMatch屬性,則是定義使用者前往的URL路徑怎樣才算是與path值匹配到。設定full代表完全相等才算匹配。設定prefix代表只要前半段的路徑與path值相等,即視為匹配。

儲存後重新整理,並前往網址「localhost:4200」,可以發現我們被重新導向到「localhost:4200/dashboard」。

之後請在app.component.html的<nav>標籤內部,加上前往dashboard組件的超連結。這樣一來,就能在Heroes組件之間切換畫面了。

二、返回上一頁

在網頁上填寫資料時,最下方一般來說會有「送出」和「取消」之類的按鈕。如果按下取消,就會回到上一頁。本節要做的功能是讓使用者能夠返回到前一個畫面。

我們希望顯示Hero詳情的畫面後,有一個按鈕能夠引導使用者回到剛剛的地方,可能是Hero清單或Dashboard。因此先在hero.detail.component.html加入按鈕:

<button (click)="goBack()">go back</button>

點擊這個按鈕,會呼叫ts檔的「goBack」方法,執行返回的動作。接下來就到ts檔完成這個方法。

首先需要先匯入「Location」的函式庫,再於建構子中注入這個服務:

import { Location } from '@angular/common';constructor(
(略)
private location: Location
) {}

這裡需特別注意,有些人可能會直接在建構子注入Location服務,心想開發工具應該會幫助我匯入。但就VS Code而言,它預設的Location並不是來自「common」函式庫,裡頭沒有待會兒要使用的操作方法。因此這邊請務必手動在上方匯入。

注入服務完成後,宣告一個名為「goBack」的方法:

goBack(): void {
this.location.back();
}

這個Location物件存有瀏覽的歷史紀錄。呼叫它的「back」方法,Angular就會將使用者引導回上一個URL。

這樣就完成了。將應用程式儲存後,現在可以試試看。從儀表板前往詳情,再按返回,或是從清單前往詳情,再按返回,是否都回到前一個地方。

加入返回鍵的詳情畫面(套用CSS)

最後請在hero.detail.component.css套用CSS樣式,使畫面好看一些:

/* HeroDetailComponent's private CSS styles */
label {
display: inline-block;
width: 3em;
margin: .5em 0;
color: #607D8B;
font-weight: bold;
}
input {
height: 2em;
font-size: 1em;
padding-left: .4em;
}
button {
margin-top: 20px;
font-family: Arial;
background-color: #eee;
border: none;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer; cursor: hand;
}
button:hover {
background-color: #cfd8dc;
}
button:disabled {
background-color: #eee;
color: #ccc;
cursor: auto;
}

--

--

Vincent Zheng
新手工程師的程式教室

我是Vincent,是個來自資管系的後端軟體工程師。當初因為學校作業,才踏出寫部落格的第一步。這裡提供程式教學文章,包含自學和工作上用到的經驗,希望能讓讀者學到東西。我的部落已搬家至 https://chikuwa-tech-study.blogspot.com/