Angular 2 необязательных параметра маршрута
Возможно ли иметь необязательный параметр маршрута в маршруте Angular 2? Я пробовал синтаксис Angular 1.x в RouteConfig, но получил ошибку ниже:
"ORIGINAL EXCEPTION: Path" /user/: id? "содержит"? ", который не разрешен в конфигурации маршрута."
@RouteConfig([
{
path: '/user/:id?',
component: User,
as: 'User'
}])
Ответы
Ответ 1
Вы можете определить несколько маршрутов с параметром и без него:
@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
Ответ 2
{path: 'users', redirectTo: 'users/'},
{path: 'users/:userId', component: UserComponent}
Таким образом, компонент не перерисовывается при добавлении параметра.
Ответ 3
Рекомендуется использовать параметр запроса, когда информация является необязательной.
Параметры маршрута или параметры запроса?
Здесь нет строгих правил. В общем,
предпочитают параметр маршрута, когда
- значение обязательно.
- значение необходимо, чтобы отличить один маршрут от другого.
предпочитаю параметр запроса, когда
- значение необязательно.
- значение является сложным и/или многовариантным.
из https://angular.io/guide/router#optional-route-parameters
Вам просто нужно вынуть параметр из пути маршрута.
@RouteConfig([
{
path: '/user/',
component: User,
as: 'User'
}])
Ответ 4
Angular 4 - Решение для адресации необязательного параметра:
ДЕЛАТЬ ЭТО:
const appRoutes: Routes = [
{path: '', component: HomeComponent},
{path: 'products', component: ProductsComponent},
{path: 'products/:id', component: ProductsComponent}
]
Обратите внимание, что маршруты products
и products/:id
называются точно такими же. Angular 4 будет правильно следовать products
для маршрутов без параметра, а если параметр будет следовать products/:id
.
Однако путь для непараметрического маршрута products
не должен иметь завершающую косую черту, иначе Angular будет неправильно рассматривать его как путь к параметру. Так что в моем случае у меня был конечный слэш для продуктов, и он не работал.
НЕ ДЕЛАЙТЕ ЭТО:
...
{path: 'products/', component: ProductsComponent},
{path: 'products/:id', component: ProductsComponent},
...
Ответ 5
Ответ rerezz довольно хорош, но у него есть один серьезный недостаток. Это заставляет User
компонент повторно запускать метод ngOnInit
.
Это может быть проблематично, когда вы выполняете какие-то тяжелые операции и не хотите, чтобы они запускались повторно при переключении с непараметрического маршрута на параметрический. Хотя эти два маршрута предназначены для имитации необязательного параметра url, они не становятся двумя отдельными маршрутами.
Вот что я предлагаю для решения проблемы:
const routes = [
{
path: '/user',
component: User,
children: [
{ path: ':id', component: UserWithParam, name: 'Usernew' }
]
}
];
Затем вы можете переместить логику, отвечающую за обработку параметра, в компонент UserWithParam
и оставить базовую логику в компоненте User
. Все, что вы делаете в User::ngOnInit
больше не будет выполняться при User::ngOnInit
от /user к /user/123.
Не забудьте поместить <router-outlet></router-outlet>
в шаблон User
.
Ответ 6
С угловым4 нам просто нужно организовать маршруты вместе в иерархии
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
}
];
Это работает для меня. Таким образом, маршрутизатор знает, какой следующий маршрут основан на параметрах идентификатора параметра.
Ответ 7
Перейдите в другой экземпляр этой проблемы, и в поисках решения к нему пришли сюда. Моя проблема заключалась в том, что я делал детей, и ленивая загрузка компонентов, а также для оптимизации вещей. Короче, если вы ленивы загружаете родительский модуль. Главное было использовать "/: id" на маршруте, и он жаловался на "/", являющийся его частью. Не точная проблема здесь, но она применяется.
Маршрутизация приложений из родительского
...
const routes: Routes = [
{
path: '',
children: [
{
path: 'pathOne',
loadChildren: 'app/views/$MODULE_PATH.module#PathOneModule'
},
{
path: 'pathTwo',
loadChildren: 'app/views/$MODULE_PATH.module#PathTwoModule'
},
...
Детские маршруты ленивы загружены
...
const routes: Routes = [
{
path: '',
children: [
{
path: '',
component: OverviewComponent
},
{
path: ':id',
component: DetailedComponent
},
]
}
];
...
Ответ 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);
}
Затем используйте matcher в вашей конфигурации маршрута:
const routes: Routes = [
{
matcher: userPageMatcher,
component: User,
}
];
Ответ 9
Я не могу комментировать, но в отношении: Angular 2 необязательный параметр маршрута
обновление для Angular 6:
import {map} from "rxjs/operators"
constructor(route: ActivatedRoute) {
let paramId = route.params.pipe(map(p => p.id));
if (paramId) {
...
}
}
См. Https://angular.io/api/router/ActivationRoute для получения дополнительной информации о маршрутизации Angular6.
Ответ 10
Столкнувшись с аналогичной проблемой с отложенной загрузкой, я сделал это:
const routes: Routes = [
{
path: 'users',
redirectTo: 'users/',
pathMatch: 'full'
},
{
path: 'users',
loadChildren: './users/users.module#UserssModule',
runGuardsAndResolvers: 'always'
},
[...]
А потом в компоненте:
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);
}
Сюда:
-
Маршрут без /
перенаправляется на маршрут с. Из-за pathMatch: 'full'
, перенаправляется только такой конкретный полный маршрут.
-
Затем users/:id
получен. Если фактическим маршрутом был users/
, id
- это ""
, поэтому проверьте его в ngOnInit
и действуйте соответственно; иначе id
- это идентификатор и продолжить.
-
Остальная часть компонента действует на selectedUser
или не определена (* ngIf и тому подобное).
Ответ 11
Queryparams лучше для вас. проверить это: Angular - Маршрутизация и навигация