在Angular 21中添加默认查询参数
在Angular 21之前,可以这样添加默认查询参数,以避免在应用的每个链接中都写入它们:
@Directive({
selector: "[myRouterLink]",
standalone: false
})
export class MyRouterLinkDirective extends RouterLink {
@Input()
set myRouterLink(commands: any[] | string | null | undefined) {
super.routerLink = commands;
}
get urlTree(): UrlTree {
const { myCustId } = this.activatedRoute.snapshot.queryParams;
const urlTree = super.urlTree;
urlTree.queryParams.myCustId = myCustId;
return urlTree;
}
}
因此,不再用 routerLink 生成链接,而是在整个应用中使用 myRouterLink。这在用查询参数进行功能开关控制的场景,以及多租户应用场景(每个页面都带有一个customerId的查询参数)中都很有用。
上述代码在Angular的若干版本中一直能正常工作,甚至在Angular 20也可以使用。但在Angular 21中,这个提交 改变了实现方式,尽管 urlTree 仍然存在,它不再被 onClick 调用,相反,onClick 调用 _urlTree,而 _urlTree 被标注为 @internal,因此Angular的编译器不允许我覆盖它:
- 之前
```typescript @HostListener('click', [ ... ]) onClick( ... ): boolean { const urlTree = this.urlTree; .... }
get urlTree(): UrlTree | null {
// ... actual implementation here ...
}
``` * 之后
```typescript @HostListener('click', [ ... ]) onClick( ... ): boolean { const urlTree = this._urlTree(); .... }
get urlTree(): UrlTree | null {
return untracked(this._urlTree);
}
/** @internal */
_urlTree = computed(() => {
// ... actual implementation here ...
})
```
有没有办法在Angular 21中实现默认查询参数功能?
解决方案
我最终使用了 Directive Composition API,它类似于类继承,但仅使用RouterLink公共API,因此除非公共API发生变化,否则未来不太容易出问题:
@Directive({
selector: "[myRouterLink]",
standalone: false,
hostDirectives: [{
directive: RouterLink,
// As the functionality of these inputs is not augmented by me,
// I can leave the values be pass unmodified from my components
// to RouterLink.
inputs: [
"target", "fragment", "queryParamsHandling", "state",
"info", "relativeTo", "preserveFragment", "skipLocationChange",
],
}],
})
export class MyRouterLinkDirective {
// Gets a hold of the directive that I'm composing
routerLink = inject(RouterLink);
private customerId = inject(MyCustomerId);
private originalQueryParams: Params = {};
@Input()
set myRouterLink(commands: any[] | string) {
this.routerLink.routerLink = commands;
this.updateQueryParams();
}
@Input()
set queryParams(params: Params) {
this.originalQueryParams = params || {};
this.updateQueryParams();
}
private updateQueryParams() {
const newQueryParams = { ...this.originalQueryParams };
if (this.customerId) {
newQueryParams.customerId = this.customerId;
}
this.routerLink.queryParams = newQueryParams;
}
}
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。