Javascript Angular 2 可选路由参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34208745/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Angular 2 optional route parameter
提问by Jeroen
Is it possible to have an optional route parameter in the Angular 2 route? I tried the Angular 1.x syntax in RouteConfig but received below error:
在 Angular 2 路由中是否可以有一个可选的路由参数?我在 RouteConfig 中尝试了 Angular 1.x 语法,但收到以下错误:
"ORIGINAL EXCEPTION: Path "/user/:id?" contains "?" which is not allowed in a route config."
“原始例外:路径“/user/:id?”包含“?”,这在路由配置中是不允许的。”
@RouteConfig([
{
path: '/user/:id?',
component: User,
as: 'User'
}])
回答by rerezz
You can define multiple routes with and without parameter:
您可以使用和不使用参数定义多个路由:
@RouteConfig([
{ path: '/user/:id', component: User, name: 'User' },
{ path: '/user', component: User, name: 'Usernew' }
])
and handle the optional parameter in your component:
并处理组件中的可选参数:
constructor(params: RouteParams) {
var paramId = params.get("id");
if (paramId) {
...
}
}
See also the related github issue: https://github.com/angular/angular/issues/3525
另请参阅相关的 github 问题:https: //github.com/angular/angular/issues/3525
回答by Martin Cremer
{path: 'users', redirectTo: 'users/', pathMatch: 'full'},
{path: 'users/:userId', component: UserComponent}
This way the component isn't re-rendered when the parameter is added.
这样,当添加参数时组件不会重新渲染。
回答by Jp_
It's recommended to use a query parameter when the information is optional.
当信息是可选的时,建议使用查询参数。
Route Parameters or Query Parameters?
There is no hard-and-fast rule. In general,
prefer a route parameter when
- the value is required.
- the value is necessary to distinguish one route path from another.
prefer a query parameter when
- the value is optional.
- the value is complex and/or multi-variate.
路由参数还是查询参数?
没有硬性规定。一般来说,
更喜欢路由参数时
- 该值是必需的。
- 该值对于区分一条路由路径和另一条路由路径是必要的。
更喜欢查询参数时
- 该值是可选的。
- 该值是复杂的和/或多变量的。
from https://angular.io/guide/router#optional-route-parameters
来自https://angular.io/guide/router#optional-route-parameters
You just need to take out the parameter from the route path.
您只需要从路由路径中取出参数即可。
@RouteConfig([
{
path: '/user/',
component: User,
as: 'User'
}])
回答by ObjectiveTC
Angular 4 - Solution to address the ordering of the optional parameter:
Angular 4 - 解决可选参数排序的解决方案:
DO THIS:
做这个:
const appRoutes: Routes = [
{path: '', component: HomeComponent},
{path: 'products', component: ProductsComponent},
{path: 'products/:id', component: ProductsComponent}
]
Note that the products
and products/:id
routes are named exactly the same. Angular 4 will correctly follow products
for routes with no parameter, and if a parameter it will follow products/:id
.
请注意,products
和products/:id
路由的名称完全相同。products
对于没有参数的路由,Angular 4 将正确遵循,如果有参数,它将遵循products/:id
.
However, the path for the non-parameter route products
must nothave a trailing slash, otherwise angular will incorrectly treat it as a parameter-path. So in my case, I had the trailing slash for products and it wasn't working.
然而,对于非参数路由路径products
必须不能有斜线,否则角度将错误地把它当作一个参数路径。所以就我而言,我有产品的尾随斜线,但它不起作用。
DON'T DO THIS:
不要这样做:
...
{path: 'products/', component: ProductsComponent},
{path: 'products/:id', component: ProductsComponent},
...
回答by matewka
rerezz's answer is pretty nice but it has one serious flaw. It causes User
component to re-run the ngOnInit
method.
rerezz 的回答非常好,但它有一个严重的缺陷。它会导致User
组件重新运行该ngOnInit
方法。
It might be problematic when you do some heavy stuff there and don't want it to be re-run when you switch from the non-parametric route to the parametric one. Though those two routes are meant to imitate an optional url parameter, not become 2 separate routes.
当您在那里执行一些繁重的工作并且在从非参数路由切换到参数路由时不希望它重新运行时,这可能会出现问题。尽管这两条路由旨在模仿可选的 url 参数,但不会成为 2 条独立的路由。
Here's what I suggest to solve the problem:
以下是我解决问题的建议:
const routes = [
{
path: '/user',
component: User,
children: [
{ path: ':id', component: UserWithParam, name: 'Usernew' }
]
}
];
Then you can move the logic responsible for handling the param to the UserWithParam
component and leave the baselogic in the User
component. Whatever you do in User::ngOnInit
won't be run again when you navigate from /userto /user/123.
然后你可以将负责处理参数的逻辑移到UserWithParam
组件中,并将基本逻辑留在User
组件中。User::ngOnInit
当您从/user导航到/user/123时,无论您做什么都不会再次运行。
Don't forget to put the <router-outlet></router-outlet>
in the User
's template.
不要忘了把<router-outlet></router-outlet>
中User
的模板。
回答by Wayne Maurer
The suggested answers here, including the accepted answerfrom rerezzwhich suggest adding multiple route entries work fine.
这里的参考答案,包括接受的答案从rerezz这表明添加多个路由条目做工精细。
However the component will be recreated when changing between the route entries, i.e. between the route entry with the parameter and the entry without the parameter.
然而,当在路由条目之间,即在带有参数的路由条目和没有参数的条目之间进行更改时,将重新创建组件。
If you want to avoid this, you can create your own route matcher which will match both routes:
如果你想避免这种情况,你可以创建自己的路由匹配器来匹配两条路由:
export function userPageMatcher(segments: UrlSegment[]): UrlMatchResult {
if (segments.length > 0 && segments[0].path === 'user') {
if (segments.length === 1) {
return {
consumed: segments,
posParams: {},
};
}
if (segments.length === 2) {
return {
consumed: segments,
posParams: { id: segments[1] },
};
}
return <UrlMatchResult>(null as any);
}
return <UrlMatchResult>(null as any);
}
Then use the matcher in your route config:
然后在路由配置中使用匹配器:
const routes: Routes = [
{
matcher: userPageMatcher,
component: User,
}
];
回答by Ravi Jadhav
With angular4 we just need to organise routes together in hierarchy
使用 angular4,我们只需要在层次结构中将路由组织在一起
const appRoutes: Routes = [
{
path: '',
component: MainPageComponent
},
{
path: 'car/details',
component: CarDetailsComponent
},
{
path: 'car/details/platforms-products',
component: CarProductsComponent
},
{
path: 'car/details/:id',
component: CadDetailsComponent
},
{
path: 'car/details/:id/platforms-products',
component: CarProductsComponent
}
];
This works for me . This way router know what is the next route based on option id parameters.
这对我有用。这样路由器就可以根据选项 id 参数知道下一条路由是什么。
回答by L.P.
Ran into another instance of this problem, and in searching for a solution to it came here. My issue was that I was doing the children, and lazy loading of the components as well to optimize things a bit. In short if you are lazy loading the parent module. Main thing was my using '/:id' in the route, and it's complaints about '/' being a part of it. Not the exact problem here, but it applies.
遇到此问题的另一个实例,并在寻找解决方案时来到这里。我的问题是我正在做孩子,以及组件的延迟加载以优化一些东西。简而言之,如果您懒惰加载父模块。主要是我在路由中使用了 '/:id',它抱怨 '/' 是它的一部分。不是这里的确切问题,但它适用。
App-routing from parent
来自父级的应用程序路由
...
const routes: Routes = [
{
path: '',
children: [
{
path: 'pathOne',
loadChildren: 'app/views/$MODULE_PATH.module#PathOneModule'
},
{
path: 'pathTwo',
loadChildren: 'app/views/$MODULE_PATH.module#PathTwoModule'
},
...
Child routes lazy loaded
子路由懒加载
...
const routes: Routes = [
{
path: '',
children: [
{
path: '',
component: OverviewComponent
},
{
path: ':id',
component: DetailedComponent
},
]
}
];
...
回答by Javier Sedano
Facing a similar problem with lazy loading I have done this:
面对与延迟加载类似的问题,我已经这样做了:
const routes: Routes = [
{
path: 'users',
redirectTo: 'users/',
pathMatch: 'full'
},
{
path: 'users',
loadChildren: './users/users.module#UserssModule',
runGuardsAndResolvers: 'always'
},
[...]
And then in the component:
然后在组件中:
ngOnInit() {
this.activatedRoute.paramMap.pipe(
switchMap(
(params: ParamMap) => {
let id: string = params.get('id');
if (id == "") {
return of(undefined);
}
return this.usersService.getUser(Number(params.get('id')));
}
)
).subscribe(user => this.selectedUser = user);
}
This way:
这边走:
The route without
/
is redirected to the route with. Because of thepathMatch: 'full'
, only such specific full route is redirected.Then,
users/:id
is received. If the actual route wasusers/
,id
is""
, so check it inngOnInit
and act accordingly; else,id
is the id and proceed.The rest of the componect acts on
selectedUser
is or not undefined (*ngIf and the things like that).
路由没有
/
被重定向到路由。由于pathMatch: 'full'
,只有这样的特定完整路由被重定向。然后,
users/:id
收到。如果实际路线是users/
,id
是""
,那么请检查它ngOnInit
并采取相应的行动;否则,id
是 id 并继续。组件的其余部分
selectedUser
是否未定义(*ngIf 和类似的东西)。
回答by mschreib28
I can't comment, but in reference to: Angular 2 optional route parameter
我无法评论,但参考:Angular 2 optional route parameter
an update for Angular 6:
Angular 6 的更新:
import {map} from "rxjs/operators"
constructor(route: ActivatedRoute) {
let paramId = route.params.pipe(map(p => p.id));
if (paramId) {
...
}
}
See https://angular.io/api/router/ActivatedRoutefor additional information on Angular6 routing.
有关Angular6 路由的更多信息,请参阅https://angular.io/api/router/ActivatedRoute。