Angular 6 - 带前缀的动态路由
Angular 6 - Dynamic Routing with Prefix
我正在开发 Angular 通用应用程序。我想创建带有自定义前缀的动态路由,但找不到与我的案例相关的任何有用文档。任何帮助将不胜感激...
详情:
我所拥有的是,我有 4 个页面,其中包含 4 个不同的动态 URL,它们是:
- 首页(
http://example.com/
)
- 分类页(
http://example.com/{category_name}
)
- 子类别页面(
http://example.com/{category_name}/{sub_category_name}
)
- 产品页面(
http://example.com/p{product_id}-{product_name}
)
- 用户页面(
http://example.com/user{user_id}-{user_name}
)
我做了什么
我已经注册了一个单一的路由来处理主页、类别和子类别页面,因为它们具有相同的 UI 和下面提到的动态类别级别,
RouterModule.forRoot([
{path: '**', component: HomeComponent, data: {title: 'Home', description: 'Homepage - quick overview.'}}
])
挣扎中:
现在,我无法添加产品和用户页面的路由,我无法理解如何在斜杠之后和 ids
之前添加 p
和 user
前缀分别在产品和用户页面中。没有这些前缀,路由工作正常。
产品和用户页面所需的 URL 示例
我正在使用 @angular/router
进行路由。
提前致谢。
通常 router
需要能够将特定输入字符串 (url
) 与给定模式 (route
) 匹配。您要确保 single 输入不匹配 multiple 模式,否则路由器将不知道前进的方向。
也就是说,Angular有一个[RouteGuard][1]
的概念。当 url 与给定路由匹配时,RouteGuard(或其任何衍生产品)会挂钩进入路由过程。
您可以使用 "matcher".
参见:https://angular.io/api/router/UrlMatcher
希望对您有所帮助。
享受吧!
谢谢@Yuriy 重新打开这个,我已经从@Ingo Bürk 的评论中得到了答案。
下面提到的 Gist 帮助我通过正则表达式创建路由。
https://gist.github.com/matanshukry/22fae5dba9c307baf0f364a9c9f7c115
为了参考,我在下面添加了源,
/**
* Copyright (c) Matan Shukry
* All rights reserved.
*/
import { UrlSegment, UrlSegmentGroup, Route } from '@angular/router';
// export type UrlMatchResult = {
// consumed: UrlSegment[]; posParams?: { [name: string]: UrlSegment };
// };
export function ComplexUrlMatcher(paramName: string, regex: RegExp) {
return (
segments: UrlSegment[],
segmentGroup: UrlSegmentGroup,
route: Route) => {
const parts = [regex];
const posParams: { [key: string]: UrlSegment } = {};
const consumed: UrlSegment[] = [];
let currentIndex = 0;
for (let i = 0; i < parts.length; ++i) {
if (currentIndex >= segments.length) {
return null;
}
const current = segments[currentIndex];
const part = parts[i];
if (!part.test(current.path)) {
return null;
}
posParams[paramName] = current;
consumed.push(current);
currentIndex++;
}
if (route.pathMatch === 'full' &&
(segmentGroup.hasChildren() || currentIndex < segments.length)) {
return null;
}
return { consumed, posParams };
}
}
如何使用,
/**
* Copyright (c) Matan Shukry
* All rights reserved.
*/
export const UserRoutes: Routes = [
{
path: 'users',
component: UserComponent,
children: [
{
path: '',
component: UserListComponent
},
{
matcher: ComplexUrlMatcher("id", /[0-9]+/),
component: UserItemComponent
},
]
}
];
@NgModule({
imports: [RouterModule.forChild(UserRoutes)],
exports: [RouterModule]
})
export class UserRoutingModule { }
要创建 http://example.com/p{product_id}-{product_name}
,我们可以将 product_id 段拆分为 :product_id
,将 product_name 段拆分为 :product_name
。然后你需要前往 app.routing.js 路由文件并将 url 设置为:
{ path: 'http://example.com/p/:product_id/-/:product_name', component: ProductComponent }
我正在开发 Angular 通用应用程序。我想创建带有自定义前缀的动态路由,但找不到与我的案例相关的任何有用文档。任何帮助将不胜感激...
详情:
我所拥有的是,我有 4 个页面,其中包含 4 个不同的动态 URL,它们是:
- 首页(
http://example.com/
) - 分类页(
http://example.com/{category_name}
) - 子类别页面(
http://example.com/{category_name}/{sub_category_name}
) - 产品页面(
http://example.com/p{product_id}-{product_name}
) - 用户页面(
http://example.com/user{user_id}-{user_name}
)
我做了什么
我已经注册了一个单一的路由来处理主页、类别和子类别页面,因为它们具有相同的 UI 和下面提到的动态类别级别,
RouterModule.forRoot([
{path: '**', component: HomeComponent, data: {title: 'Home', description: 'Homepage - quick overview.'}}
])
挣扎中:
现在,我无法添加产品和用户页面的路由,我无法理解如何在斜杠之后和 ids
之前添加 p
和 user
前缀分别在产品和用户页面中。没有这些前缀,路由工作正常。
产品和用户页面所需的 URL 示例
我正在使用 @angular/router
进行路由。
提前致谢。
通常 router
需要能够将特定输入字符串 (url
) 与给定模式 (route
) 匹配。您要确保 single 输入不匹配 multiple 模式,否则路由器将不知道前进的方向。
也就是说,Angular有一个[RouteGuard][1]
的概念。当 url 与给定路由匹配时,RouteGuard(或其任何衍生产品)会挂钩进入路由过程。
您可以使用 "matcher".
参见:https://angular.io/api/router/UrlMatcher
希望对您有所帮助。 享受吧!
谢谢@Yuriy 重新打开这个,我已经从@Ingo Bürk 的评论中得到了答案。 下面提到的 Gist 帮助我通过正则表达式创建路由。 https://gist.github.com/matanshukry/22fae5dba9c307baf0f364a9c9f7c115
为了参考,我在下面添加了源,
/**
* Copyright (c) Matan Shukry
* All rights reserved.
*/
import { UrlSegment, UrlSegmentGroup, Route } from '@angular/router';
// export type UrlMatchResult = {
// consumed: UrlSegment[]; posParams?: { [name: string]: UrlSegment };
// };
export function ComplexUrlMatcher(paramName: string, regex: RegExp) {
return (
segments: UrlSegment[],
segmentGroup: UrlSegmentGroup,
route: Route) => {
const parts = [regex];
const posParams: { [key: string]: UrlSegment } = {};
const consumed: UrlSegment[] = [];
let currentIndex = 0;
for (let i = 0; i < parts.length; ++i) {
if (currentIndex >= segments.length) {
return null;
}
const current = segments[currentIndex];
const part = parts[i];
if (!part.test(current.path)) {
return null;
}
posParams[paramName] = current;
consumed.push(current);
currentIndex++;
}
if (route.pathMatch === 'full' &&
(segmentGroup.hasChildren() || currentIndex < segments.length)) {
return null;
}
return { consumed, posParams };
}
}
如何使用,
/**
* Copyright (c) Matan Shukry
* All rights reserved.
*/
export const UserRoutes: Routes = [
{
path: 'users',
component: UserComponent,
children: [
{
path: '',
component: UserListComponent
},
{
matcher: ComplexUrlMatcher("id", /[0-9]+/),
component: UserItemComponent
},
]
}
];
@NgModule({
imports: [RouterModule.forChild(UserRoutes)],
exports: [RouterModule]
})
export class UserRoutingModule { }
要创建 http://example.com/p{product_id}-{product_name}
,我们可以将 product_id 段拆分为 :product_id
,将 product_name 段拆分为 :product_name
。然后你需要前往 app.routing.js 路由文件并将 url 设置为:
{ path: 'http://example.com/p/:product_id/-/:product_name', component: ProductComponent }