如何解决角度9-解析给定网址的每个参数
假设我们有以下几种网址:
[1] /home/users/:id
[2] /home/users/:id/posts/:id
[3] /home/users/:id/posts/:id/comments/:id
我想创建一个方法 parseUrl(url:string):any [] {} ,该方法接受一个url并返回包含该参数的每个参数的数组网址。因此,parseUrl('/home/users/:id/posts/:id/comments/:id')
将导致[userId,postId,commentId]
如何实现?
天真的方法: 假设我们知道哪些网址段可以包含参数(在这种情况下,是 users , posts 和 comments ),我们可以将网址除以{{ 1}}字符,检查该段是否等于 users 或 posts 或 comments ,最后将后续段作为url。>
'/'
为什么这很烂?->实际上,它与网址的结构高度相关。例如,如果我也有这样的网址: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;
}
,那么/home/users/new-post
将被视为参数。
使用new-post
或ActivatedRoute
: 使用* ActivatedRouteSnapshot`的 params 属性似乎更好,因为它是免费的根据我们网址的结构。这里的问题是,在我的特定情况下,我只能检索最后一个URL段的参数。所以
ActivatedRouteSnapshot
将导致仅包含parseUrl(route: ActivatedRouteSnapshot) {
return route.params;
}
的对象给出{'id': 5}
作为当前URL。这是因为(至少我认为)我已经为用户,帖子和评论配置了惰性加载模块。所以我有3个路由模块,一个匹配路由/home/users/10/posts/10/comments/5
,第二个匹配users/:id
,第三个匹配posts/:id
。我发现ActivatedRouteSnapshot将它们视为3个单独的url段,每个段具有一个参数,而不是一个具有3个参数的单个url。
最后,是否有一种编程的通用方法可以从 Anuglar 9 中的网址获取每个参数?
解决方法
您可以使用可选的参数,而不是使用“必需的”路由参数。该参数使您可以通过路由发送对象。
尝试以下
路径配置
{ path: '/home/users/',component: UsersComponent }
呼叫路线
<a [routerLink]="['/home/users',{ data: JSON.stringify([userId,postId,commentId]) }]">...</a>
或
this.router.navigate(['/home/users',commentId]) }]);
结果网址
http://myapp.com/home/users;data=...
检索数据
JSON.parse(this.router.snapshot.paramMap.get('data'));
,
您将需要递归遍历路由器树以收集所有参数。 仅当您的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);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。