Angular 2 可选路由参数

IT技术 javascript angular
2021-01-21 06:02:32

在 Angular 2 路由中是否可以有一个可选的路由参数?我在 RouteConfig 中尝试了 Angular 1.x 语法,但收到以下错误:

“原始例外:路径“/user/:id?”包含“?”,这在路由配置中是不允许的。”

@RouteConfig([
{
    path: '/user/:id?',
    component: User,
    as: 'User'
}])
6个回答

您可以使用和不使用参数定义多个路由:

@RouteConfig([
    { path: '/user/:id', component: User, name: 'User' },
    { path: '/user', component: User, name: 'Usernew' }
])

并处理组件中的可选参数:

constructor(params: RouteParams) {
    var paramId = params.get("id");

    if (paramId) {
        ...
    }
}

另请参阅相关的 github 问题:https : //github.com/angular/angular/issues/3525

对于那些想知道为什么RouteParams不导入组件的人,请检查:stackoverflow.com/a/36792261/806202解决方案是使用ActivatedRouteroute.snapshot.params['routeParam']
2021-03-16 06:02:32
这种方法的旧但主要问题是每个路由都被视为唯一的路由,这使得组件无法重用。
2021-03-20 06:02:32
如果我错了,请纠正我,但此解决方案仅在数组中的路由顺序颠倒时才对我有用,即带有参数的路由出现在另一个之前。在我这样做之前,路由器只匹配没有参数的路由。
2021-04-04 06:02:32
正如@teleaziz 所指出的,附加参数将重新渲染组件。为了避免这种情况,Martin Cremer 的回答;添加一个带有空白参数值的“redirectTo”根,对我来说非常有用stackoverflow.com/a/49159166/1364650 - 但这很hacky,我认为他们应该正确地支持可选的路由参数。
2021-04-04 06:02:32
这个解决方案仍然适用吗?我注意到从“User”移动到“UserNew”将重新实例化“User”组件
2021-04-07 06:02:32
{path: 'users', redirectTo: 'users/', pathMatch: 'full'},
{path: 'users/:userId', component: UserComponent}

这样,当添加参数时,组件不会重新渲染。

@Simon_Weaver 我同意。我找到了另一个使用匹配器的解决方案,它没有这个问题:stackoverflow.com/a/56391974/664533
2021-03-25 06:02:32
如果您可以在浏览器中查看 URL 的尾部斜杠,则此答案是最好的。考虑一个代表“未定义 id”的值,例如/users/all/users/home,将“全部”或“家”读作id,如果它与您的魔法值匹配,则简单地忽略它。然后上面的第一行变成redirectTo: 'users/home'或任何你决定的。对我来说,尾随斜线真的很明显是错误的。
2021-03-26 06:02:32
这个答案是最好的。它不会重新渲染同一个组件,也不需要多个组件。
2021-03-27 06:02:32
最好的答案,但我添加pathMatch: 'full'了重定向,否则users/admin在我的情况下也重定向了类似的路径
2021-04-03 06:02:32
这是一个简单的咒语,但非常牢不可破:D 最好的解决方案!
2021-04-12 06:02:32

当信息是可选的时,建议使用查询参数。

路由参数还是查询参数?

没有硬性规定。一般来说,

更喜欢路由参数时

  • 该值是必需的。
  • 该值对于区分一条路由路径和另一条路由路径是必要的。

更喜欢查询参数时

  • 该值是可选的。
  • 该值是复杂的和/或多变量的。

来自https://angular.io/guide/router#optional-route-parameters

您只需要从路由路径中取出参数即可。

@RouteConfig([
{
    path: '/user/',
    component: User,
    as: 'User'
}])
仅供参考,该锚链接不再有效。新链接似乎是路由参数:必需还是可选?
2021-03-28 06:02:32
更改可选路由参数会重新渲染组件,但更改 queryParams 不会。此外,如果您在路线导航之前解析某些数据,则每次更改可选路线参数时都会请求它。
2021-04-03 06:02:32

Angular 4 - 解决可选参数排序的解决方案:

做这个:

const appRoutes: Routes = [
  {path: '', component: HomeComponent},
  {path: 'products', component: ProductsComponent},
  {path: 'products/:id', component: ProductsComponent}
]

请注意,productsproducts/:id路由的名称完全相同。products对于没有参数的路由,Angular 4 将正确遵循,如果有参数,它将遵循products/:id.

然而,对于非参数路由路径products必须不能有斜线,否则角度将错误地把它当作一个参数路径。所以就我而言,我有产品的尾随斜线,但它不起作用。

不要这样做:

...
{path: 'products/', component: ProductsComponent},
{path: 'products/:id', component: ProductsComponent},
...
不幸的是,这个解决方案会阻止 Angular 在 products 和 products/:id 之间重用组件。该组件将被重新实例化。
2021-03-19 06:02:32
您可以访问 :id1、:id2 等参数以及 ProductsComponent 中请求的 url,如下所示: this.route.url.first() .mergeMap((url) => { // console.log('1:检测到 url 更改' + url); return this.route.params.do((params) => { // console.log('2: url + params 检测到更改' + params["id1"] + ' ' + params ["id2"]); this.id1 = params["id1"]; this.id2 = params["id2"]; }) })
2021-03-24 06:02:32
如果两者都去ProductsComponent,你如何处理那里的可选参数?
2021-04-03 06:02:32
请记住,您也可以传递data给组件,即使是同一组件,每个路由也可能不同。{path: 'products', component: ProductsComponent, data: { showAllProducts: true} },可以使用示例,然后检查showAllProducts. 比检查 null 好一点,但对于更简单的情况,两者都可能很好。
2021-04-09 06:02:32
@Kodiak - 我不认为这是正确的。我的理解是,在 app.module.ts 中,ProductsComponent 被实例化一次,然后 Angular 引擎在每个可导航事件(products 和 products/:id 等)上重新使用实例化的 ProductsComponent。您能否解释或演示 ProductsComponent 如何在上面的代码中重新实例化,以及您将如何防止重新实例化?
2021-04-11 06:02:32

rerezz 的回答非常好,但它有一个严重的缺陷。它会导致User组件重新运行该ngOnInit方法。

当您在那里执行一些繁重的工作并且在从非参数路由切换到参数路由时不希望它重新运行时,这可能会出现问题。尽管这两条路由旨在模仿可选的 url 参数,但不会成为 2 条独立的路由。

以下是我解决问题的建议:

const routes = [
  {
    path: '/user',
    component: User,
    children: [
      { path: ':id', component: UserWithParam, name: 'Usernew' }
    ]
  }
];

然后你可以将负责处理参数的逻辑移到UserWithParam组件中,并将基本逻辑留在User组件中。User::ngOnInit当您从/user导航/user/123时,无论您做什么都不会再次运行

不要忘了把<router-outlet></router-outlet>User的模板。

如果性能至关重要,避免重新创建组件是一件好事。我有另一个解决方案,它也避免了重新创建组件:stackoverflow.com/a/56391974/664533
2021-03-19 06:02:32