각도 2 옵션 경로 매개 변수


180

Angular 2 라우트에 선택적 라우트 매개 변수를 사용할 수 있습니까? RouteConfig에서 Angular 1.x 구문을 시도했지만 아래 오류가 발생했습니다.

"원본 예외 : 경로"/ user / : id? "에 경로 구성에서 허용되지 않는"? "가 포함되어 있습니다."

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

답변:


298

매개 변수를 사용하거나 사용하지 않고 여러 경로를 정의 할 수 있습니다.

@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


11
내가 틀렸다면 수정하십시오.하지만이 솔루션은 배열의 경로 순서가 반대 인 경우에만 유효합니다. 즉 매개 변수가있는 경로가 다른 경로보다 먼저 발생했습니다. 내가 할 때까지 라우터는 매개 변수가없는 경로 만 일치했습니다.
Aviad P.

10
이 솔루션은 여전히 ​​적용됩니까? 나는 '사용자 구성 요소를 인스턴스화를 다시 것 "UserNew"에서 "사용자"에서 이동주의
teleaziz

19
오래되었지만이 방법의 주요 문제점은 각 경로가 고유 한 경로로 취급되어 구성 요소 재사용이 불가능하다는 것입니다.
고통

4
@teleaziz가 지적했듯이 매개 변수를 추가하면 구성 요소가 다시 렌더링됩니다. 이것을 피하기 위해 Martin Cremer의 답변; 빈 매개 변수 값을 가진 'redirectTo'루트를 추가, 나를 위해 큰 일 : stackoverflow.com/a/49159166/1364650 -하지만 꽤 해키, 나는 그들이 단지 적절하게 선택 경로 매개 변수를 지원한다고 생각합니다.
Vincent Sels

2
RouteParams구성 요소로 가져 오지 않는 이유가 궁금한 분은 stackoverflow.com/a/36792261/806202를 확인하십시오 . 해결책은 다음과 ActivatedRoute같습니다.route.snapshot.params['routeParam']
Arsen Khachaturyan

89
{path: 'users', redirectTo: 'users/', pathMatch: 'full'},
{path: 'users/:userId', component: UserComponent}

이렇게하면 매개 변수가 추가 될 때 구성 요소가 다시 렌더링되지 않습니다.


6
이 답변이 최고입니다. 동일한 구성 요소를 다시 렌더링하지 않으며 여러 구성 요소가 필요하지 않습니다.
Rex

4
가장 좋은 답변이지만 pathMatch: 'full'리디렉션에 추가 했습니다. 그렇지 않으면 경로 users/admin가 경로 가 리디렉션됩니다.
Valeriy Katkov

4
이 답변은 브라우저에서 볼 수 있듯이 URL에 슬래시가 있으면 가장 좋습니다. 예를 들어 /users/all또는 정의되지 않은 ID를 나타내는 값을 고려 하거나 /users/home'all'또는 'home'을로 읽은 id다음 마법의 값과 일치하면 무시하십시오. 그런 다음 위의 첫 번째 줄 redirectTo: 'users/home'이 결정됩니다. 나에게 후행 슬래시는 실제로 무언가 잘못된 것으로 눈에.니다.
Simon_Weaver

@Simon_Weaver 동의합니다. 이 문제가없는 매처를 사용하는 다른 솔루션을 찾았습니다. stackoverflow.com/a/56391974/664533
Wayne Maurer

1
그것은 간단한 주문이지만 깨지지 않습니다. : D 최고의 솔루션!
Verri

45

정보가 선택적인 경우 쿼리 매개 변수를 사용하는 것이 좋습니다.

경로 매개 변수 또는 쿼리 매개 변수?

강력하고 빠른 규칙은 없습니다. 일반적으로

라우트 매개 변수를 선호

  • 값이 필요합니다.
  • 값은 한 경로 경로를 다른 경로 경로와 구별하기 위해 필요합니다.

때 쿼리 매개 변수를 선호

  • 값은 선택 사항입니다.
  • 값은 복잡하거나 다변량입니다.

에서 https://angular.io/guide/router#optional-route-parameters

경로 경로에서 매개 변수를 꺼내기 만하면됩니다.

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

6
선택적 경로 매개 변수를 변경하면 구성 요소가 다시 렌더링되지만 queryParams는 변경되지 않습니다. 또한 경로 탐색 전에 일부 데이터를 해결하는 경우 선택적 경로 매개 변수를 변경할 때마다 요청됩니다.
Rakhat

1
참고로 앵커 링크는 더 이상 작동하지 않습니다. 새 링크는 라우트 매개 변수 인 것 같습니다 : 필수 또는 선택적?
spottedmahn

20

각도 4-선택적 매개 변수의 순서를 해결하는 솔루션 :

이 작업을 수행:

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

주의 productsproducts/:id경로가 정확히 이름이 동일합니다. 각도 4는 products매개 변수가없는 경로에 대해 올바르게 따르며 매개 변수가 있으면 경로를 따릅니다 products/:id.

그러나, 비 매개 변수 경로에 대한 경로가 products있어야 하지 , 후행 슬래시를 다른 각도 잘못 매개 변수 경로로 취급됩니다. 그래서 내 경우에는 제품에 대한 슬래시가 있었고 작동하지 않았습니다.

이 작업을 수행하지 마십시오 :

...
{path: 'products/', component: ProductsComponent},
{path: 'products/:id', component: ProductsComponent},
...

둘 다 ProductsComponent로 이동하는 경우 선택적 매개 변수를 어떻게 처리합니까?
Arwin

1
ProductsComponent에서 요청한 URL뿐만 아니라 : id1, : id2 등의 매개 변수에 액세스 할 수 있습니다. this.route.url.first () .mergeMap ((url) => {// console.log ( '1 : url 변경 감지 '+ url); this.route.params.do ((params) => {// console.log ('2 : url + params 변경 감지 '+ params [ "id1"] +' '+ params 반환 [ "id2"]); this.id1 = params [ "id1"]; this.id2 = params [ "id2"];})})
ObjectiveTC

2
data구성 요소도 전달할 수 있으며, 이는 동일한 구성 요소로도 각 경로마다 다를 수 있습니다. 예제를 {path: 'products', component: ProductsComponent, data: { showAllProducts: true} },사용할 수 있으며를 확인하십시오 showAllProducts. 그런 다음 null을 확인하는 것이 조금 더 좋지만 간단한 경우에는 괜찮을 것입니다.
Simon_Weaver

1
불행히도이 솔루션은 Angular가 제품과 products / : id간에 구성 요소를 재사용하지 못하게합니다. 구성 요소가 다시 설치됩니다.
코디 악

@ Kodiak-나는 그것이 옳지 않다고 생각합니다. app.module.ts에서 ProductsComponent는 한 번 인스턴스화되고 각 엔진은 탐색 가능한 각 이벤트 (products 및 products / : id 등)에서 인스턴스화 된 ProductsComponent를 재사용한다는 것을 이해합니다. 위 코드에서 ProductsComponent를 다시 인스턴스화하는 방법과 다시 인스턴스화를 방지하는 방법을 설명하거나 설명 할 수 있습니까?
ObjectiveTC

11

rerezz의 대답은 꽤 좋지만 심각한 결함이 있습니다. 그것은 원인이 User재 실행에 구성 요소 ngOnInit방법을.

매개 변수가없는 경로에서 매개 변수 경로로 전환 할 때 무거운 작업을 수행하고 다시 실행하지 않으려는 경우 문제가 될 수 있습니다. 이 두 경로는 선택적인 url 매개 변수를 모방하기위한 것이지만 2 개의 개별 경로가되지는 않습니다.

문제를 해결하기 위해 제안하는 내용은 다음과 같습니다.

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

그런 다음 매개 변수 처리를 담당하는 논리를 UserWithParam구성 요소로 이동하고 기본 논리를 User구성 요소 에 그대로 둡니다 . / user 에서 / user / 123으로User::ngOnInit 이동 하면 무엇을하든 다시 실행되지 않습니다 .

를 붙이 잊지 마세요 <router-outlet></router-outlet>에서 User의 템플릿입니다.


성능이 중요한 경우 구성 요소를 다시 작성하지 않는 것이 좋습니다. 구성 요소가 다시 작성되는 것을 피하는 또 다른 솔루션이 있습니다. stackoverflow.com/a/56391974/664533
Wayne Maurer

4

여러 경로 항목을 추가하는 것이 좋습니다 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);
 }

그런 다음 경로 구성에서 매처를 사용하십시오.

const routes: Routes = [
    {
        matcher: userPageMatcher,
        component: User,
    }
];

@ KevinBeal 나는 AOT와 함께 작동하는 꽤 많은 매처를 구현했습니다. 여기에 오는 오류는 무엇입니까?
Wayne Maurer

죄송합니다. 다른 것입니다. 내 매처는 AOT와 함께 작동합니다.
케빈 Beal

이것은 조금 까다
롭지 만이

4

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 
  }
];

이것은 나를 위해 작동합니다. 이 방법으로 라우터는 옵션 ID 매개 변수를 기반으로 다음 경로가 무엇인지 알 수 있습니다.


1

이 문제의 또 다른 사례를 발견하고 해결책을 찾기 위해 여기에 왔습니다. 내 문제는 내가 아이들을하고 있었고, 구성 요소를 게으르게로드하고 물건을 조금 최적화하는 것이 었습니다. 간단히 말하면 부모 모듈을 느리게로드하는 것입니다. 가장 중요한 것은 경로에서 '/ : 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
      },
    ]
  }
];
...


0

지연 로딩과 비슷한 문제에 직면 하여이 작업을 수행했습니다.

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하고 그에 따라 행동; 그렇지 않으면 idID이며 진행됩니다.

  • 나머지 구성 요소의 역할 selectedUser은 정의되지 않았거나 정의되지 않았습니다 (* ngIf 및 이와 유사한 것).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.