我编写了一些 Router Prototype 覆盖,使处理查询参数变得更容易:
想法是在路由器上调用一个方法,通过参数轻松管理路由,而不必每次都导出函数/重新声明功能。
创建一个包含原型覆盖定义的index.d.ts 文件:
// Ensure this is treated as a module.
export { };
declare module '@angular/router' {
interface Router {
updateQueryParams(activatedRoute: ActivatedRoute, params: Params): Promise<boolean>;
setQueryParams(activatedRoute: ActivatedRoute, params: Params): Promise<boolean>;
removeQueryParams(activatedRoute: ActivatedRoute, ...keys: string[]): Promise<boolean>;
}
}
重要:
确保在使用此原型覆盖之前导入此文件,我刚刚将我的原型导入添加到app.module.ts:
import './shared/prototype-overrides/router.prototypes';
设置查询参数
这只会设置指定的查询参数,不会合并参数。
场景
您正在以下路线上:
http://localhost:4200/#/some-route?param1=Test&param2=test2
并且您想SET将查询参数设置为param3=HelloWorld,并删除其他参数。
用法
this.router.setQueryParams(this.activatedRoute, { param3: 'HelloWorld' });
// Will route to http://localhost:4200/#/some-route?param3=HelloWorld
原型功能实现
Router.prototype.setQueryParams = function (activatedRoute: ActivatedRoute, params: Params): Promise<boolean> {
const context: Router = this;
if (isNullOrUndefined(activatedRoute)) {
throw new Error('Cannot update the query parameters - Activated Route not provided to use relative route');
}
return new Promise<boolean>((resolve) => {
setTimeout(() => {
resolve(context.navigate([], {
relativeTo: activatedRoute,
queryParams: params
}));
});
});
};
更新查询参数
这仅用于轻松更新 queryParams,它将合并路由中的查询参数,因此您没有重复的查询参数。
场景
您正在以下路线上:
http://localhost:4200/#/some-route?param1=Test&param2=test2
并且您只想更新一个查询参数,param1 到 param1=HelloWorld,而保留其他参数不变。
用法
this.router.updateQueryParams(this.activatedRoute, { param1: 'HelloWorld' });
// Will route to http://localhost:4200/#/some-route?param1=HelloWorld¶m2=test2
原型功能实现
Router.prototype.updateQueryParams = function (activatedRoute: ActivatedRoute, params: Params): Promise<boolean> {
const context: Router = this;
if (isNullOrUndefined(activatedRoute)) {
throw new Error('Cannot update the query parameters - Activated Route not provided to use relative route');
}
// setTimeout required because there is an unintended behaviour when rapidly firing router updates in the same repaint cycle:
//
// NavigationCancel - Navigation ID 2 is not equal to the current navigation id 3
// https://stackoverflow.com/a/42802182/1335789
return new Promise<boolean>((resolve) => {
setTimeout(() => {
resolve(context.navigate([], {
relativeTo: activatedRoute,
queryParams: params,
queryParamsHandling: 'merge'
}));
});
});
};
删除查询参数
场景
您正在以下路线上:
http://localhost:4200/#/some-route?param1=Test&param2=test2&param3=test3
并且您只想删除一个(或多个,按字符串分隔的键)查询参数param1,而保留其他参数不变。
用法
this.router.removeQueryParams(this.activatedRoute, 'param1');
// Will route to http://localhost:4200/#/some-route?param2=test2¶m3=test3
//Removing multiple parameters:
this.router.removeQueryParams(this.activatedRoute, 'param1', 'param3');
// Will route to http://localhost:4200/#/some-route?param2=test2
原型功能实现
Router.prototype.removeQueryParams = function (activatedRoute: ActivatedRoute, ...keys: string[]): Promise<boolean> {
const context: Router = this;
const currentParams: any = {};
Object.keys(activatedRoute.snapshot.queryParams).forEach(key => {
currentParams[key] = activatedRoute.snapshot.queryParams[key];
});
keys?.forEach(key => {
delete currentParams[key];
});
return new Promise<boolean>((resolve) => {
setTimeout(() =>
resolve(context.setQueryParams(activatedRoute, currentParams))
);
});
};