Angular 带有路由参数的前缀路由
Angular routing for prefix with route parameter
我想实现用户个人资料页面。使用
会很简单
/profile/user123
路径使用:
app-routing.module
{
path: 'profile',
loadChildren: () => import('./modules/profile/profile.module').then(m => m.ProfileModule)
},
简介-routing.module
{
path: ':username',
component: ProfileComponent
},
但是,我想做一些花哨的事情 URL,比如 /@user123
。
不幸的是,我没有找到任何关于如何做的线索。我尝试了以下方法:
app-routing.module
{
path: '@:username',
loadChildren: () => import('./modules/profile/profile.module').then(m => m.ProfileModule)
},
简介-routing.module
{
path: '',
component: ProfileComponent
},
但是没用。
我只想到一件事,那就是使用 Guard 检查 '@' 前缀,否则重定向到 /not-found
页面。
关于如何使用“Angular”方式进行路由的任何想法?
您可以使用自定义路由 matcher
来达到预期的效果。
- app-routing.module.ts
{
path: 'profile',
loadChildren: () => import('./modules/profile/profile.module').then(m => m.ProfileModule)
},
- 在 profile-routing.module.ts 中,您可以通过提供
custom URL-matching function
来指定路由:
{
matcher: (url) => {
// You can have regex as per your requirement
if (url.length === 1 && url[0].path.match(/^@[\w]+$/gm)) {
return {
consumed: url,
posParams: {
username: new UrlSegment(url[0].path.substr(1), {}) // <--- creating UrlSegment by getting rid of @ from url path
}
};
}
return null;
},
component: ProfileComponent
}
- 在 profile.component.ts 文件中,您可以将
username
读取为:
username$!: Observable<string | null>;
constructor(private activatedRoute: ActivatedRoute) { }
ngOnInit(): void {
this.username$ = this.activatedRoute.paramMap
.pipe(
map((params: ParamMap) => params.get('username'))
);
}
- 在 profile.component.html 中,您可以将用户名打印为:
<p>
Profile: {{username$ | async}}
</p>
- 现在只需导航至 url
/profile/@user123
,您应该能够在 ProfileComponent 中获得 user123
作为用户名
Siddhant 提供的解决方案非常好,但我想要 /@user123
而不是 /profile/@user123
,所以我稍微调整了一下。
app-routing.module.ts
{
matcher: (url) => {
if (url.length === 1 && url[0].path.match(/^@[\w.\-]+$/gm)) { // <--- added a hyphen and a dot, since \w only does [a-zA-Z0-9_]
return {
consumed: url,
posParams: {
username: new UrlSegment(url[0].path.substr(1), {}) // <--- creating UrlSegment by getting rid of @ from url path
}
};
}
return null;
},
loadChildren: () => import('./modules/profile/profile.module').then(m => m.ProfileModule)
},
个人资料。routing.module.ts
{
path: '',
component: ProfileComponent
},
profile.component.ts
ngOnInit(): void {
this.activatedRoute.paramMap.subscribe(paramMap => {
this.userService.getUser(paramMap.get('username')).subscribe(res => {
if (res) {
this.user = res;
} else {
this.router.navigate([Utils.ARTICLE_NOT_FOUND_URL]);
}
});
});
}
我正在添加另一个答案,因为我还需要使用 @user123/edit
路径,但它不适用于原始解决方案。所以这是如何做到的:
app-routing.module.ts
{
matcher: (url) => {
console.log(url);
if (url[0].path.match(/^@[\w.\-]+$/gm)) { <-- removed check for url length
return {
consumed: url.slice(0, 1), <-- return the rest of the URL instead of the whole URL (this routing rule should only consume @user123 and return the rest of the URL, which is /edit)
posParams: {
username: new UrlSegment(url[0].path.substr(1), {}) // <--- creating UrlSegment by getting rid of @ from url path
}
};
}
return null;
},
loadChildren: () => import('./modules/profile/profile.module').then(m => m.ProfileModule)
},
简介.routing.module.ts
{
path: '',
component: ProfileComponent
},
{
path: 'edit',
component: EditProfileComponent
},
我想实现用户个人资料页面。使用
会很简单/profile/user123
路径使用:
app-routing.module
{
path: 'profile',
loadChildren: () => import('./modules/profile/profile.module').then(m => m.ProfileModule)
},
简介-routing.module
{
path: ':username',
component: ProfileComponent
},
但是,我想做一些花哨的事情 URL,比如 /@user123
。
不幸的是,我没有找到任何关于如何做的线索。我尝试了以下方法:
app-routing.module
{
path: '@:username',
loadChildren: () => import('./modules/profile/profile.module').then(m => m.ProfileModule)
},
简介-routing.module
{
path: '',
component: ProfileComponent
},
但是没用。
我只想到一件事,那就是使用 Guard 检查 '@' 前缀,否则重定向到 /not-found
页面。
关于如何使用“Angular”方式进行路由的任何想法?
您可以使用自定义路由 matcher
来达到预期的效果。
- app-routing.module.ts
{
path: 'profile',
loadChildren: () => import('./modules/profile/profile.module').then(m => m.ProfileModule)
},
- 在 profile-routing.module.ts 中,您可以通过提供
custom URL-matching function
来指定路由:
{
matcher: (url) => {
// You can have regex as per your requirement
if (url.length === 1 && url[0].path.match(/^@[\w]+$/gm)) {
return {
consumed: url,
posParams: {
username: new UrlSegment(url[0].path.substr(1), {}) // <--- creating UrlSegment by getting rid of @ from url path
}
};
}
return null;
},
component: ProfileComponent
}
- 在 profile.component.ts 文件中,您可以将
username
读取为:
username$!: Observable<string | null>;
constructor(private activatedRoute: ActivatedRoute) { }
ngOnInit(): void {
this.username$ = this.activatedRoute.paramMap
.pipe(
map((params: ParamMap) => params.get('username'))
);
}
- 在 profile.component.html 中,您可以将用户名打印为:
<p>
Profile: {{username$ | async}}
</p>
- 现在只需导航至 url
/profile/@user123
,您应该能够在 ProfileComponent 中获得
user123
作为用户名
Siddhant 提供的解决方案非常好,但我想要 /@user123
而不是 /profile/@user123
,所以我稍微调整了一下。
app-routing.module.ts
{
matcher: (url) => {
if (url.length === 1 && url[0].path.match(/^@[\w.\-]+$/gm)) { // <--- added a hyphen and a dot, since \w only does [a-zA-Z0-9_]
return {
consumed: url,
posParams: {
username: new UrlSegment(url[0].path.substr(1), {}) // <--- creating UrlSegment by getting rid of @ from url path
}
};
}
return null;
},
loadChildren: () => import('./modules/profile/profile.module').then(m => m.ProfileModule)
},
个人资料。routing.module.ts
{
path: '',
component: ProfileComponent
},
profile.component.ts
ngOnInit(): void {
this.activatedRoute.paramMap.subscribe(paramMap => {
this.userService.getUser(paramMap.get('username')).subscribe(res => {
if (res) {
this.user = res;
} else {
this.router.navigate([Utils.ARTICLE_NOT_FOUND_URL]);
}
});
});
}
我正在添加另一个答案,因为我还需要使用 @user123/edit
路径,但它不适用于原始解决方案。所以这是如何做到的:
app-routing.module.ts
{
matcher: (url) => {
console.log(url);
if (url[0].path.match(/^@[\w.\-]+$/gm)) { <-- removed check for url length
return {
consumed: url.slice(0, 1), <-- return the rest of the URL instead of the whole URL (this routing rule should only consume @user123 and return the rest of the URL, which is /edit)
posParams: {
username: new UrlSegment(url[0].path.substr(1), {}) // <--- creating UrlSegment by getting rid of @ from url path
}
};
}
return null;
},
loadChildren: () => import('./modules/profile/profile.module').then(m => m.ProfileModule)
},
简介.routing.module.ts
{
path: '',
component: ProfileComponent
},
{
path: 'edit',
component: EditProfileComponent
},