角度:替换网址中的段

时间:2019-07-08 12:37:25

标签: angular angular-routing angular-router

此问题是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具有“客户”),而其余网址保持原样?

2 个答案:

答案 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的其他参数