Angular 9 - 解析给定 url 的每个参数

dc_Bita98

假设我们有这些类型的网址:

[1] /home/users/:id

[2] /home/users/:id/posts/:id

[3] /home/users/:id/posts/:id/comments/:id

我想创建一个方法parseUrl(url: string): any[] {},它接受一个 url 并返回一个包含该 url 的每个参数的数组。那么,parseUrl('/home/users/:id/posts/:id/comments/:id')将导致[userId, postId, commentId]我如何实现这一目标?

幼稚的方法:假设我们知道哪些 url 段可以包含参数(在这种情况下, users postscomments),我们可以按'/'字符拆分 url,检查该段是否等于userspostscomments,最后取后续段作为网址。

parseUrl(url: string): any[] {
    let params = new Array<any>();
    url.split('/')
      .filter((segment, index, urlSegments) => index > 0 && ['users', 'posts', 'comments'].includes(urlSegments[index - 1]))
      .forEach(segment => params.push(segment))
    return params;
}

为什么这很糟糕?--> 它实际上与 url 的结构高度耦合。例如,如果我也有这样的 url: /home/users/new-postnew-post则将被视为参数。

使用ActivatedRouteor ActivatedRouteSnapshot使用*ActivatedRouteSnapshot`params属性似乎更好,因为它不受我们 url 的结构影响。这里的问题是,在我的特殊情况下,我只能检索最后一个 url 段的参数。所以

parseUrl(route: ActivatedRouteSnapshot) {
    return route.params;
  }

将导致一个对象只包含例如{'id': 5}给出/home/users/10/posts/10/comments/5作为当前 url。这是因为(至少我认为)我已经用户帖子评论配置了延迟加载模块所以我有 3 个路由模块,一个匹配路由,第二个匹配,第三个匹配我发现 ActivatedRouteSnapshot 将它们视为 3 个单独的 url 段,每个段带有一个参数,而不是一个带有 3 个参数的单个 url。users/:idposts/:idcomments/:id

那么最后,是否有一种编程的通用方法可以从Anuglar 9 中的 url 获取每个参数

弗雷德里克·伯克

您需要递归地遍历路由器树以收集所有参数。此代码段仅适用,如果您的 paramKeys 是唯一的,那么

/home/users/:id/posts/:id/comments/:id将需要是/home/users/:userId/posts/:postId/comments/:commentId如果您想保留旧的 paramkey 名称,则需要相应地调整代码段。

它可能看起来像这样:

export parseUrl(route: ActivatedRouteSnapshot): Map<string,string> {
  const result = reduceRouterChildrenParams(route.root.firstChild, new Map<string, string>());
  return result;
}

reduceRouterChildrenParams(routerChild: ActivatedRouteSnapshot | null, data: Map<string, string>): RouteWalkerResult {
  if (!routerChild) {
      return data;
  }
  for (const paramMapKey of routerChild.paramMap.keys) {
    data.set(paramMapKey, routerChild.paramMap.get(paramMapKey)!);
  }
  return routerChild.children.reduce((previousValue, currentValue) => {
    return reduceRouterChildrenParams(currentValue, previousValue);
  }, data);
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章