我們的路由,配置到目前為止,已經可以切換頁面,但是如果我們要讀取 URL 的參數列,比如說這樣:
我有一個參數叫 A
,他的 value
是 123
,我想要把它讀進來,該怎麼做呢?
首先我們要先知道,在定義路由時,可以這樣寫:
{ path: 'home/:id', component: HomepageComponent}
這邊的 :id
,在我們的定義裡,是一個一定要傳入的參數,也就是說,我這邊要輸入 home/123
、home/AAA
... 等等的 URL,才能成功比對路由位址,顯示畫面,總之就是 :id
不能為空。當然只要是冒號開頭,後面接自己喜歡的變數名稱都可以,不一定要是 id
。
上面這個例子是一定要傳入參數 id,但也有不一定要傳入參數的方式,就是用我們熟悉的 Query string:
http://localhost:4200/home?name1=value1&name2=value2
就是在網址後面用問號串接,並以 &
分隔每一個參數。
要實現這個功能,需要用到 ActivatedRoute
這個 Service。我們想在 HomepageComponent
上面實作,所以我們把它注入進 HomepageComponent
:
// homepage.component.ts
import { ActivatedRoute, ParamMap} from '@angular/router';
constructor(private route: ActivatedRoute) { }
然後在 ngOnit()
加入取得參數的程式碼:
name;
ngOnInit() {
this.name = this.route.snapshot.queryParamMap.get('name');
}
這樣就會抓到第一次載入這個 component 時的變數 name
。
http://localhost:4200/home?name=fansen
結果:
要注意傳參數還有一種格式,是使用分號分隔的,長的像這樣:
http://localhost:4200/home;name=fansen;number=123;
Angular 也可以吃這種參數格式,但程式碼就要稍微改一下:
name;
ngOnInit() {
this.name = this.route.snapshot.paramMap.get('name');
}
用 paramMap
取代 queryParamMap
,就可以吃這種格式的參數。
如果我們要實作「登入成功後轉向首頁或是其他頁面」,就會需要讓Angular 幫我們自動轉向頁面,這時候就要使用另一個 Service Router
,我們一樣把它注入到 Component 裡:
// homepage.component.ts
import { ActivatedRoute, ParamMap, Router } from '@angular/router';
constructor(private route: ActivatedRoute, private router: Router) { }
接下來我們調用 navigate()
這個 function,第一個參數要傳入陣列,跟之前 routerLink
的概念一樣,如果網址是/login/name/info
的話,就傳入 ['/login','name','info']
,當然也可以夾入變數:
// homepage.component.ts
navigate() {
this.router.navigate(['/login']);
}
然後 binding 到一個 button 上:
// homepage.component.html
<button (click)="navigate()">Navigate To Login</button>
這樣點擊按鈕就會轉向 http://localhost:4200/login
了:
還有另一個 function 叫 navigateURL()
,這個 function 傳入的參數就是一個字串,以剛剛的網址為例,就是傳入 /login/name/info
即可:
// homepage.component.ts
navigateURL() {
this.router.navigateByUrl('/login');
}
然後除了最常用的第一個參數外,我們還發現有個 extras?: NavigationExtras
參數,我們可以拿它來做點甚麼:
比如說在導向新頁面時,想要將 Query String 加進去,當然我們可以用自幹的方式,拼出一個 Query String 再串接到網址後面,
類似這樣的想法:
queryString = '?name=name123&naumber=1'
url = '/login' + queryString
但是有了 NavigationExtras
,就不需要這麼麻煩了,我們只需要建一個 NavigationExtras
物件,然後把 Query String 像物件一樣一組一組擺進去:
// homepage.component.ts
navigate() {
const options: NavigationExtras = {
queryParams : {
name: 'name123',
number: 1
}
};
this.router.navigate(['/login'], options);
}
轉向新頁面時就會加上參數:
queryParams
也可以和 routerLink
一起用:
<a routerLink="/login" [queryParams]="{ name: 'name123', number: 1}"></a>
最後如果不想讓別人看到路由位址的話,可以在 NavigationExtras
加入 skipLocationChange: true
,
這樣在跳轉頁面時,URL就不會改變,但是 queryParams
的參數一樣會傳送出去:
// homepage.component.ts
const options: NavigationExtras = {
queryParams : {
name: 'name123',
number: 1
},
skipLocationChange: true
};
可以看到 URL 還是在 /home
但是頁面已經切到/login
。傳出去的 name123
也有正確的被抓到。
搭配 routerLink
的話,在屬性加入 skipLocationChange
即可:
<a routerLink="/login" [queryParams]="{ name: 'name123', number: 1}" skipLocationChange></a>
其實路由是一個很大的主題,這邊講的功能都只是冰山一角,比方說在登入機制方面,Angular 也有設計一些配套措施,歡迎大家做更深的研究。