Angular 16 有個新特性,可以大幅簡化取得路由參數的語法,對新手老手來說都是福音,這篇文章我就來說說這個全新路由特性,相信這個特性大家看了都喜歡!😍
Angular 15 之前如何取得路由參數
以下我先示範 Angular 15 之前,元件是如何取得路由參數的:
-
建立專案與預設頁面
# 建立 demo1 專案
ng new demo1 --routing --style=css
# 進入 demo1 資料夾
cd demo1
# 建立 HomeComponent 頁面
ng g c home --skip-selector
# 啟動開發伺服器
npm start
-
修正 src/app/app.component.html
網頁
<router-outlet></router-outlet>
-
修正 src/app/app-routing.module.ts
路由
const routes: Routes = [
{ path: 'home/:id', component: HomeComponent },
];
-
修正 src/app/home/home.component.ts
元件
注入 ActivatedRoute
並取得 id
路由參數
import { Component, OnInit, inject } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
route = inject(ActivatedRoute);
id: string | null = '';
ngOnInit(): void {
this.route.paramMap.subscribe(p => {
this.id = p.get('id');
});
}
}
-
修正 src/app/home/home.component.html
範本
<p>home id = {{id}}!</p>
-
連線到 http://localhost:4200/home/123 網頁
Angular 16 之後如何取得路由參數
-
先調整 AppRoutingModule
在路由模組加上 bindToComponentInputs: true
屬性設定!
@NgModule({
imports: [RouterModule.forRoot(routes, {
bindToComponentInputs: true
})],
exports: [RouterModule]
})
export class AppRoutingModule { }
如果是 Standalone Component 獨立元件架構的話,由於並沒有 AppModule 的存在,所以設定方式稍微有點不太一樣。但你只要在 bootstrapApplication
的 providRouter()
的第二個參數加上 withComponentInputBinding()
即可!
bootstrapApplication(App, {
providers: [
provideRouter(routes,
//... other features
withComponentInputBinding() // <-- enable this feature
)
],
});
-
修正 src/app/home/home.component.ts
元件
你可以發現新的版本少寫了很多 Code,使用上非常直觀!👍
import { Component, Input, OnInit } from '@angular/core';
@Component({
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
@Input() id = '';
ngOnInit(): void {
console.log(this.id);
}
}
常見問題解答
-
改用 @Input() id
之後,如果網址列上的路由參數變更時,會像 this.route.paramMap.subscribe()
這樣可以訂閱更新後的值嗎?
Ans: 會的,你會即時拿到更新後的路由參數,同時也會觸發 ngOnChanges()
hook 喔!👍
-
我可否透過 @Input() name
拿到 Query String 查詢字串 name
的值?
Ans: 可以的!完全相同的語法即可拿到,非常方便啊!👍
不僅如此,你還可以拿到 data
property 與 resolver
的值,都用簡單的 @Input()
語法即可!😍
-
我可否透過 @Input() id
拿到值之後,自動轉型成 number
型別?
Ans: 我們透過 ActivateRoute
取得到的值一定是 string
型別,如果你需要轉型成 number
或 boolean
型別都要手動轉換過,有點麻煩。從 Angular 16.1 開始,你可以透過 transform
函式做到自動轉型,例如使用 numberAttribute
或 booleanAttribute
等轉換函式進行宣告,讓你拿到資料時直接就是轉換過的型別。
範例如下:
@Input({transform: numberAttribute}) id = 0;
完整範例如下:
import { Component, Input, OnChanges, OnInit, SimpleChanges, numberAttribute } from '@angular/core';
@Component({
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit, OnChanges {
@Input({transform: numberAttribute}) id = 0;
ngOnInit(): void {
console.log(typeof(this.id), this.id);
}
ngOnChanges(changes: SimpleChanges): void {
console.log(typeof(this.id), this.id);
}
}
相關連結