Angular 2可选路由参数

Jer*_*oen 144 javascript angular

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

"ORIGINAL EXCEPTION:Path"/ user /:id?"包含"?",这在路由配置中是不允许的."

@RouteConfig([
{
    path: '/user/:id?',
    component: User,
    as: 'User'
}])
Run Code Online (Sandbox Code Playgroud)

rer*_*ezz 251

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

@RouteConfig([
    { path: '/user/:id', component: User, name: 'User' },
    { path: '/user', component: User, name: 'Usernew' }
])
Run Code Online (Sandbox Code Playgroud)

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

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

    if (paramId) {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

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

  • 旧的但这种方法的一个主要问题是每条路线都被视为唯一路线,它使组件重用变得不可能. (13认同)
  • 如果我错了,请纠正我,但只有当数组中的路由顺序颠倒时,这个解决方案才适用于我,即参数的路由发生在另一个之前.在我这样做之前,路由器只匹配没有参数的路由. (10认同)
  • 这个解决方案仍然适用吗?我注意到从"User"移动到"UserNew"将重新实例化"User"组件 (9认同)
  • 如@teleaziz所述,追加参数将重新渲染组件.为了避免这种情况,Martin Cremer的回答; 添加一个带有空白参数值的'redirectTo'根,对我来说非常有用:/sf/answers/3441141651/ - 但这非常hacky,我认为他们应该只是正确支持可选的路由参数. (3认同)
  • 对于那些想知道为什么`RouteParams`不能导入到组件的人,请检查:/sf/answers/2575458301/。解决方法是使用`ActivatedRoute`:`route.snapshot.params ['routeParam']` (2认同)

Mar*_*mer 59

{path: 'users', redirectTo: 'users/'},
{path: 'users/:userId', component: UserComponent}
Run Code Online (Sandbox Code Playgroud)

这样,添加参数时不会重新呈现组件.

  • 这个答案是最好的。它不会重新渲染相同的组件,并且不需要多个组件。 (6认同)
  • 如果您可以在浏览器中查看 URL 的尾部斜杠,则此答案是最好的。考虑一个表示“未定义 id”的值,例如“/users/all”或“/users/home”,将“all”或“home”读作“id”,如果它与您的匹配,则忽略它魔法值。然后上面的第一行变成 `redirectTo: 'users/home'` 或任何你决定的。对我来说,尾随斜杠真的很明显是错误的。 (5认同)
  • 最好的答案,但我添加了`pathMatch:'full'`来重定向,否则像`users/admin`这样的路径也会重定向到我的情况 (3认同)

Jp_*_*Jp_ 36

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

路由参数或查询参数?

没有严格的规则.一般来说,

更喜欢路线参数

  • 该值是必需的.
  • 该值是区分一条路径与另一条路径的必要条件.

更喜欢查询参数

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

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

您只需要从路径路径中取出参数.

@RouteConfig([
{
    path: '/user/',
    component: User,
    as: 'User'
}])
Run Code Online (Sandbox Code Playgroud)

  • 更改可选路由参数会重新呈现组件,但更改queryParams则不会.此外,如果您在路线导航之前解决某些数据,则每次更改可选路线参数时都会请求它. (6认同)

Obj*_*eTC 18

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

做这个:

const appRoutes: Routes = [
  {path: '', component: HomeComponent},
  {path: 'products', component: ProductsComponent},
  {path: 'products/:id', component: ProductsComponent}
]
Run Code Online (Sandbox Code Playgroud)

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

然而,对于非参数路由路径products必须不能有斜线,否则角度将错误地把它当作一个参数路径.所以在我的情况下,我有产品的尾部斜线,它没有工作.

不要这样做:

...
{path: 'products/', component: ProductsComponent},
{path: 'products/:id', component: ProductsComponent},
...
Run Code Online (Sandbox Code Playgroud)

  • 不幸的是,这个解决方案将阻止 Angular 重用 products 和 products/:id 之间的组件。该组件将被重新实例化。 (4认同)
  • 请记住,您也可以将"数据"传递给组件,即使对于同一组件,每条路径也可能不同.示例`{path:'products',component:ProductsComponent,data:{showAllProducts:true}},`可以使用`然后检查`showAllProducts`.稍微好一点,然后检查null,但对于更简单的情况,或许可能没问题. (2认同)

mat*_*wka 9

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

当你在那里做一些沉重的东西并且当你从非参数路径切换到参数路径时不希望它重新运行时,它可能会有问题.虽然这两条路线都是为了模仿一个可选的url参数,但不是两条不同的路由.

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

const routes = [
  {
    path: '/user',
    component: User,
    children: [
      { path: ':id', component: UserWithParam, name: 'Usernew' }
    ]
  }
];
Run Code Online (Sandbox Code Playgroud)

然后,您可以将负责处理param的逻辑移动到UserWithParam组件,并将基本逻辑保留在User组件中.User::ngOnInit当您从/ user导航到/ user/123时,无论您执行什么操作都不会再次运行.

别忘了把它<router-outlet></router-outlet>放在User模板中.


Way*_*rer 8

这里的参考答案,包括接受的答案rerezz这表明添加多个路由条目做工精细。

然而,当在路由条目之间,即在带有参数的路由条目和没有参数的条目之间进行更改时,将重新创建组件。

如果你想避免这种情况,你可以创建自己的路由匹配器来匹配两条路由:

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);
 }
Run Code Online (Sandbox Code Playgroud)

然后在路由配置中使用匹配器:

const routes: Routes = [
    {
        matcher: userPageMatcher,
        component: User,
    }
];
Run Code Online (Sandbox Code Playgroud)


Sup*_*del 7

可通过三种方式通过路由将路由参数从一个组件发送到另一组件。但首先在组件相关的.ts文件中导入这些库并在构造函数中定义

private route: ActivatedRoute
private router: Router
Run Code Online (Sandbox Code Playgroud)

第一种方式:所需的路由参数

//Route Configuration
{path: 'user/:id', component: UserDetailComponent}

//Set Hyperlink/routerLink
<a [routerLink]="['/user', user.id]"></a> 

 //Requesting Url after click on hyperlink
 http://localhost:4200/user/6

//Now you can read id value in navigated component
this.route.snapshot.paramMap.get('id');
Run Code Online (Sandbox Code Playgroud)

第二种方式:可选路径参数

//Route Configuration
    {path: 'user', component: UserDetailComponent}
    
    //Set Hyperlink/routerLink
    <a [routerLink]=['/user', {name: userName, status: true}]"></a>


//Requesting Url after click on hyperlink
    http://localhost:4200/user;name:userNameValue;status:true

//Now you can read values in navigated component
    this.route.snapshot.paramMap.get('userId');
    this.route.snapshot.paramMap.get('userName');
Run Code Online (Sandbox Code Playgroud)

第三种方式:可选路径参数

//Route Configuration
    {path: 'user', component: UserDetailComponent}
    
    //Set Hyperlink/routerLink
    <a [routerLink]="['/user']"  [queryParms]="{userId:'911', status:true}"></a>

    //Requesting Url after click on hyperlink
    http://localhost:4200/user?userId=911&status=true

    
    //Now you can read values in navigated component
    this.route.snapshot.paramMap.get('userId');
    this.route.snapshot.paramMap.get('userName');
Run Code Online (Sandbox Code Playgroud)

参考:https ://qastack.mx/programming/44864303/send-data-through-routing-paths-in-angular


小智 6

使用 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 
  }
];
Run Code Online (Sandbox Code Playgroud)

这对我有用。这样路由器就可以根据选项 id 参数知道下一条路由是什么。