此问题是SO上以下现有问题的重复:
Angular router: how to replace param?
Generically replace Angular 2 route parameter and navigate
Angular 6 router - replace some of the parameters of the current route
Angular2-router: How to only change a parameter of a route?
How can I change a specific, internal route parameter in Angular2
这些问题的答案都不能完全解决替换url中一个段的问题,因此我再次提出这个问题。
总结我的情况:
这些是我项目中的一些路线(我自己没有提出,所以请多多包涵)
/:customer/static/part/of/url
/:customer/other/static/stuff
/something/for/the/:customer
/something/without/anything
/other/stuff/:customer/might/need
参数“:customer”出现在URL的不同位置。我的问题是,该客户ID可能会在后端更改,而无需前端采取任何措施。我正在听后端的更改,因此必须相应地调整URL,以防客户ID发生更改。
一个简单的string.replace不会起作用,因为从技术上讲,客户ID实际上可能实际上是“静态”或“其他”。
问题:
如何分析当前网址(ActivatedRoute?),以仅替换与客户ID相关的网址的一部分(paramMap具有“客户”),而其余网址保持原样?
答案 0 :(得分:0)
要读取字符串中的文本模式,我建议使用正则表达式。
例如,如果您的客户ID类似于“ 123456”,则正则表达式可以为/ \ d {6} /(斜线用于描述正则表达式模式,而不是url):
let url = '/something/for/the/123456' // 123456 denotes :customer here
let pattern = /\d{6}/;
let customerId = url.match(pattern);
请谨慎定义仅与URL中的客户ID匹配的模式。
您可以在这里找到有关JavaScript正则表达式的更多信息:https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/RegExp
我几乎忘记了,您可以使用String.replace()函数替换字符串中的模式: https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/String/replace
答案 1 :(得分:0)
我确实编写了自己的生成器。这是代码:
import { ActivatedRoute } from "@angular/router";
const defaultExtras: {
params: any,
preserveMatrix: boolean,
recursive: boolean,
preserveChildMatrix: boolean,
replaceChildParams: boolean
} = {
params: {},
preserveMatrix: true,
recursive: true,
preserveChildMatrix: false,
replaceChildParams: true
};
export function routerPathGenerator(
route: ActivatedRoute,
extras?: { params?: any, preserveMatrix?: boolean, recursive?: boolean, preserveChildMatrix?: boolean, replaceChildParams?: boolean }
): any[] {
const mergedExtras = { ...defaultExtras, ...extras };
const path: any[] = [...replaceRouteParams(route.routeConfig.path.split('/'), { ...route.snapshot.params, ...mergedExtras.params })];
if (mergedExtras.preserveMatrix) {
path.push(replaceMatrixParams(route, mergedExtras.params));
}
if (mergedExtras.recursive && route.children.length > 0) {
path.push(...routerPathGenerator(route.children[0], {
params: mergedExtras.replaceChildParams ? mergedExtras.params : {},
preserveMatrix: mergedExtras.preserveChildMatrix,
recursive: mergedExtras.recursive,
preserveChildMatrix: mergedExtras.preserveChildMatrix,
replaceChildParams: mergedExtras.replaceChildParams
}));
}
return path;
}
function replaceRouteParams(parts: string[], params: Object): any[] {
return (parts || [])
.map(part => (part.startsWith(':') && params.hasOwnProperty(part.substring(1)) ? params[part.substring(1)] : part));
}
function replaceMatrixParams(route: ActivatedRoute, params: Object): any {
const matrix: any = {};
Object.keys(route.snapshot.params)
.forEach(key =>
(route.routeConfig.path.split('/').some(p => p === ':' + key) ?
'' :
matrix[key] = params.hasOwnProperty(key) ? params[key] : route.snapshot.params[key])
)
return matrix;
}
假设我们有这样的网址:
http://some.domain/warehouses/5;c=7;d=8/moves/42/items;a=1;b=2?e=77&f=88
其中'/ warehouses'指向带有路径的延迟加载模块:
const routes: Routes = [
{ path: '', component: WarehousesComponent },
{ path: ':id', redirectTo: ':id/stocks', pathMatch: 'full' },
{ path: ':id', component: WarehousesComponent, children: [
{ path: 'stocks', component: StocksComponent },
{ path: 'moves', component: MovesComponent, children: [
{ path: '', redirectTo: 'items', pathMatch: 'full' },
{ path: ':moveId/items', component: ItemsComponent },
{ path: 'initial', component: InitialComponent }
] }
] }
];
如果我在WarehousesComponent中运行下一个代码
const commands = routerPathGenerator(this.route, {
params: {
id: 8,
moveId: 24,
c: 17,
a: 666
},
preserveChildMatrix: true
});
this.router.navigate(commands, { queryParamsHandling: 'preserve', relativeTo: this.route.parent });
我将导航到
http://some.domain/warehouses/8;c=17;d=8/moves/24/items;a=666;b=2?e=77&f=88
我认为这是您的情况,只是检查routerPathGenerator的其他参数