AngularのwithComponentInputBindingでルーティングパラメータを扱う
Angular v17で導入された withComponentInputBinding
とSignal Inputの組み合わせにより、ルーティングパラメータの扱いが劇的に改善されました。この記事では、従来の方法から新しい方法への移行パターンを紹介します。(超今更な記事ではありますが、マイグレーションを後回しにしてたプロジェクトがあって、生成AIに参考情報として食べさせるために書きました)
従来の方法と新しい方法の比較
1. ActivatedRouteからparamsを取得する方法
ActivatedRoute
から params
を得るためには、 paramMap
をsubscribeするか、snapshot.paramMap
から得るかの2つのパターンがありました。
従来の方法
@Component({
// ...
})
export class UserDetailComponent implement OnInit {
userId: string;
route = inject(ActivatedRoute);
ngOnInit() {
// Pattern paramMap
this.route.paramMap.subscribe(params => {
this.userId = params['id'];
});
// Pattern snapshot
this.userId = this.route.snapshot.paramMap.get('id');
}
}
新しい方法
withComponentInputBinding
を使うと、以下のようにシンプルに書くことができます。この機能は、以下の情報をコンポーネントの入力に直接バインドします:
- クエリパラメータ
- パスパラメータとマトリックスパラメータ
- 静的ルートデータ
- リゾルバーからのデータ
@Component({
// ...
})
export class UserDetailComponent {
userId = input<string>();
}
2. paramsMapをsubscribeして他の処理をしている場合
paramsMap
が変更する度に、それにあわせて他の処理をしていた場合もあるかと思います。
従来の方法
@Component({
// ...
})
export class UserDetailComponent implement OnInit {
route = inject(ActivatedRoute);
userService = inject(UserService);
userId: string;
userData: IUser;
ngOnInit() {
this.route.paramMap.subscribe(params => {
this.userId = params.get('id')!;
this.loadUserData();
});
}
private loadUserData() {
this.userService.getUser(this.userId).subscribe(data => {
this.userData = data;
});
}
}
新しい方法
その場合は、Signals で入ってくることを活かして effect
で処理を行います。また、ルートデータに一致するキーがない場合、入力は undefined
に設定されることに注意が必要です。これは、ルートからデータが削除された場合(クエリパラメータが削除された場合など)に、以前の情報が保持されるのを防ぐためです。
@Component({
// ...
})
export class UserDetailComponent {
route = inject(ActivatedRoute);
userService = inject(UserService);
userId = input<string>();
userData: IUser;
constructor() {
effect(() => {
const id = this.userId();
if (id) {
this.userService.getUser(id).subscribe(data => {
this.userData = data;
});
}
})
}
}
新しい方法の利点
従来の方法では ActivatedRoute
の注入と subscribe
が必要でしたが、新しい方法では Signal Input だけで済むようになりました。これにより、コードがより宣言的になり、型安全性も向上します。
また、Signal Input を使用することで、コンポーネントの入力が単純になり、テストが書きやすくなります。特に、ルーティングパラメータの変更に応じて他の処理を行う場合、effect
を使用することで、より宣言的なコードを書くことができます。
まとめ
withComponentInputBinding
とSignal Inputの組み合わせにより、ルーティングパラメータの扱いが大幅に改善されました。コードが簡潔になり、型安全性も向上し、パフォーマンスも改善されるという、まさに一石三鳥の機能です。
新しいプロジェクトではもちろん、既存のプロジェクトでも段階的に移行を検討する価値があるでしょう。特に、複雑なルーティングパラメータの処理を行っているコンポーネントでは、その効果を実感できるはずです。
Discussion