Angular-第9課-路由攜帶參數

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

試想一下,若要瀏覽某個特定的東西,例如購物平台的商品,網址會有什麼不同?答案是網址後面會夾帶資料,像是商品編號或名稱,藉此對應想要瀏覽的東西。本課要練習的是在URL攜帶參數,取得特定的資料。

課程關鍵字:#路由參數 #模板字串 #占位符

一、路由上的參數

目前Hero的詳情只會在點選Hero清單的其中一個項目時才會顯示。若隨著新功能的開發,使其他地方也能連結至該畫面,那麼將HeroDetailComponent內嵌在HeroesComponent當中就不適當了。

為了讓未來需要的地方也能透過點選來顯示詳情,做法其實和上一課前往另一個URL,顯示Heroes組件一樣,只是需要路由來導向到HeroDetail組件罷了。但由於只會顯示一個Hero的資料,所以需要在路由上「指定」要哪一個Hero。

首先請開啟之前建立的路由模組(app-routing-module.ts),在routes陣列中添加一組路由:

{ path: 'detail/:id', component: HeroDetailComponent }

上面的「:id」代表參數,舉例來說,本課完成後,當前往「detail/11」這個URL,就會顯示id為11的Hero之詳情資料。參數名稱和網址路徑可以自己取名,不一定要用id或detail。其中id這個名稱,之後會在ts檔中使用,以取出參數值。

路由的部份已經設定完成,接下來要將heroes-component.html底部的「<app-hero-detail>」移除。因為這個Hero詳情將不會只有配合清單顯示資料而已,它還得配合下一課要做的新畫面(儀表板),甚至也有使用者直接貼上URL的情形。

現在將HTML標籤拿掉了,那它之後要怎麼顯示呢?別擔心,本課完成後它仍會在上一課提到的app.component.html的「<router-outlet>」位置出現。

二、在超連結加入參數

為了能夠在點選清單項目時顯示HeroDetail組件,需要修改它們的操作行為。請先開啟heroes-component.html修改清單元素。

原本的操作行為是點擊後會呼叫ts檔的「onSelect」方法,並透過CSS綁定變換樣式,現在請將這兩項移除,連同ts檔的方法和selectedHero資料成員。然後在<li>內部加入超連結。完成後會像這個樣子:

在清單項目添加帶有參數的超連結

三、取得路由資訊

現在html檔已經準備就緒了,本節要調整的是其他ts檔。當使用者前往「/detail/:id」的路由時,HeroDetail組件應該被創建,並顯示對應id的hero資料。做法是在它被創建時取得路由中的id,再透過HeroService的幫助來取得對應的資料。

請開啟hero.detail.component.ts,注入HeroService和ActivatedRoute。後者保存著連結到這個組件的路由資訊,其中也包括前面提到的id參數值。

接下來宣告一個名為「getHero」的方法,讓它在ngOnInit生命週期函數被呼叫。實作的內容如下:

getHero(): void {
const id: number = +this.route.snapshot.paramMap.get('id');
this.heroService.getHero(id)
.subscribe(hero => this.hero = hero);
}

首先從ActivatedRoute物件的參數表(paramMap),取出名稱為「id」的參數,並透過「+」符號轉換為數值型態。這個名稱必須與路由模組中所定義的相同(:id)。接著再透過HeroService,取得指定id的hero資料。

但目前在Service中還沒有這個方法,因此下一步要做的就是建立它:

getHero(id: number): Observable<Hero> {
this.messageService.add(`HeroService: fetched hero, id = ${id}`);
return of(HEROES.find(hero => hero.id === id));
}

在前面的課程我們開發過Message的功能,希望可以用來顯示取得資料的歷史紀錄,如今派上用場了。在取得單一hero資料時,先添加一條訊息到紀錄中。這裡傳入的字串使用「模板字串」,類似Java的String.format方法。

隨後從外部的HEROES陣列尋找指定的元素,這邊使用了「find」方法。前面的hero代表陣列中的元素,先取好名字,與後方相呼應。後方則是判斷式,當元素的id屬性值與getHero方法所傳入的一樣,就相當於找到了。

重新整理瀏覽器,我們已經能點選Hero清單上的項目,甚至直接貼上URL,來檢視Hero詳情,它會在app.component.html的「<router-outlet>」位置出現。

利用路由參數取得特定資料

四、模板字串

在上一節,我們傳送字串給MessageService時利用了「模板字串」,這一節就稍微介紹一下。

使用模板字串,開發者內心會有一套字串的格式,例如:「產品名稱:XXX,價格:123」。如果想藉由模板定義一個字串,要使用「反引號(‵)」來包圍起來,例如:

`產品名稱:${name},價格:${price}`

而中間的金錢符號與大括號稱為「占位符」,它定義了變數要插入的地方。因此在使用時,前面的name和price變數會被引入進來,組合成一個字串。

--

--

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

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