59

나는 최신 Angular 2 릴리스 후보로 작업중인 응용 프로그램을 업그레이드하는 중입니다. 이 작업의 일환으로 NgModule 스펙을 사용하고 응용 프로그램의 모든 부분을 모듈로 마이그레이션하려고합니다. 대부분 라우팅과 관련된 문제는 예외입니다.

"@angular/common": "2.0.0-rc.5",
"@angular/compiler": "2.0.0-rc.5",
"@angular/core": "2.0.0-rc.5",
"@angular/forms": "0.3.0",
"@angular/http": "2.0.0-rc.5",
"@angular/platform-browser": "2.0.0-rc.5",
"@angular/platform-browser-dynamic": "2.0.0-rc.5",
"@angular/router": "3.0.0-rc.1",

내 응용 프로그램은 여러 모듈이 부모 모듈의 자식으로 함께 붙어있는 모듈 구성으로 제작되었습니다. 예를 들어, 알림 모듈, 사용자 모듈 및 Telphony 모듈 (예 :)으로 구성된 관리 모듈이 있습니다. 이 모듈에 대한 경로는 다음과 같아야합니다.

/admin/notifications/my-notifications
/admin/users/new-user
/admin/telephony/whatever

이전 버전의 라우터에서는 "children"을 사용하여 쉽게 구현할 수있었습니다.

export const AdminRoutes: RouterConfig = [
   {
      path: "Admin",
      component: AdminComponent,
      Children: [
         ...UserRoutes,
         ...TelephonyRoutes,
         ...NotificationRoutes
      ]
   }
]

다른 파일에서 하위 모듈의 일부로 개별 모듈 경로도 정의 할 수 있습니다.

export const UserRoutes: RouterConfig = [
    {
       path: "users",
       component: userComponent,
       children: [
           {path: "new-user", component: newUserComponent}
       ]
    }

]

이것은 모두 잘 작동했습니다. 모듈로 업그레이드하는 과정에서 모든 것을 개별 라우팅 파일로 옮겼습니다. 이제이 두 가지가 더 비슷해 보입니다.

const AdminRoutes: Routes = [
    {path: "admin", component: AdminComponent}
] 

export const adminRouting = RouterModule.forChild(AdminRoutes)

const UserRoutes: Routes = [
       path: "users",
       component: userComponent,
       children: [
           {path: "new-user", component: newUserComponent}
       ]
] 

export const userRouting = RouterModule.forChild(UserRoutes)

이 모든 것을 갖추어서 userRouting을 가져 오는 UsersModule과 adminRoutes 및 UsersModule을 가져 오는 AdminModule이 있습니다. 내 생각에, UsersModule은 AdminModule의 자식이므로 라우팅은 이전과 같은 방식으로 작동합니다. 불행하게도, 그렇게하지 않아도 사용자 경로로 끝납니다.

/users/new-user 

대신에

/admin/users/new-user

또한,이 때문에 새 사용자 구성 요소가 내 응용 프로그램의 스타일 및 탐색을 중단시키는 내 관리 구성 요소의 라우터 콘센트에로드되지 않습니다.

나는 내 AdminModule의 자식으로 내 UserModule의 경로를 참조하는 방법을 생각해 낼 수 없다. 나는 오래된 방법을 시도하고 두 모듈에있는 경로에 대한 오류가 발생했습니다. 분명히 이것이 새로 발표 된 이래로, 몇몇 경우의 문서는 제한되어 있습니다.

누구든지 제공 할 수있는 도움을 주시면 대단히 감사하겠습니다!


7 답변


47

좋아, 주말의 더 좋은 부분을 위해 이것으로 주위를 노련하게 한 후에 나는 그것을 나의 끝에서 달리게했다. 결국 나를 위해 일한 것은 다음을 수행하는 것이 었습니다.

  • 모두 내보내기Routes라우팅하려는 모든 모듈에 대해 다음 중 하나를 가져 오지 마십시오.RouterModule.forChild()자식 모듈에서.
  • 수출...마다하위 모듈 정의의 하위 경로 정의에서 볼 수있는 하위 구성 요소입니다.
  • 가져 오기 (Typescript를 의미)import키워드)를 사용하여 모든 하위 경로를 평소처럼 사용하고...연산자를 올바른 경로로 통합하십시오. 나는 그것을 경로를 정의하는 자식 모듈과 함께 작동시키지 못했지만, 부모 모듈에서 그것을 갖는 것은 잘 작동한다 (그리고 느슨한 로딩과 호환 가능하다).

내 경우에는 다음과 같은 계층 구조에 3 가지 레벨이 있습니다.

  • 루트 (/)
    • 편집자 (editor/:projectId)
      • 검색어 (query/:queryId)
      • 페이지 (page/:pageId)
    • 앞 (about)

다음 정의는 나를 위해 작동합니다./editor/:projectId/query/:queryId통로:

// app.routes.ts
import {editorRoutes}                   from './editor/editor.routes'

// Relevant excerpt how to load those routes, notice that the "editor/:projectId"
// part is defined on the parent
{
    path: '',
    children: [
        {
            path: 'editor/:projectId',
            children: [...editorRoutes]
            //loadChildren: '/app/editor/editor.module'
        },
    ]
}

편집기 경로는 다음과 같습니다.

// app/editor/editor.routes.ts
import {queryEditorRoutes}              from './query/query-editor.routes'
import {pageEditorRoutes}               from './page/page-editor.routes'

{
    path: "", // Path is defined in parent
    component : EditorComponent,
    children : [
        {
            path: 'query',
            children: [...queryEditorRoutes]
            //loadChildren: '/app/editor/query/query-editor.module'
        },
        {
            path: 'page',
            children: [...pageEditorRoutes]
            //loadChildren: '/app/editor/page/page-editor.module'
        }
    ]
}

그리고 QueryEditor의 마지막 부분은 다음과 같습니다 :

// app/editor/query/query-editor.routes.ts
{
    path: "",
    component : QueryEditorHostComponent,
    children : [
        { path: 'create', component : QueryCreateComponent },
        { path: ':queryId', component : QueryEditorComponent }
    ]
}

그러나,이 작품을 만들기 위해, 일반Editor수입해야한다.수출하다QueryEditor그리고QueryEditor수출해야한다.QueryCreateComponentQueryEditorComponent이는 가져 오기와 함께 표시됩니다. 이 작업을 수행하지 않으면 다음 행의 오류가 발생합니다.Component XYZ is defined in multiple modules.

이 설정에서는 지연로드가 제대로 작동하므로 자식 경로를 가져 오지 않아야합니다.


  • 이것은 유망 해 보입니다. 그리고 그 시간을 내 주셔서 감사합니다. 모듈 정의에서 약간을 명확히 할 수 있습니까? 라우팅 파일에서 정확히 내보내는 내용은 무엇입니까? Routes []를 내보내거나 라우팅 파일에서 RouterModule.forChild ()를 내보내고 있습니까? 그리고 모듈을 내보내기 / 가져 오기하여 모듈을 볼 수있게합니까? 지금까지의 시도로 인해 RouterOutlet이 두 번 정의 된 다음 모듈에 Routes []를 내보내려는 중에 unexpect [object, Object]가 내보내지는 중 오류가 발생했습니다. - John Ackerman
  • 아, 죄송합니다 ... 어떻게 든 귀하의 의견을 읽은 다음 답장을하지 않았습니다. 내가 함께했던 전체 설정을 볼 수 있습니다.bitbucket.org/marcusriemer/esqulino/src/… - Marcus Riemer
  • 나는이 대답을하기 위해 약간의 시간을 보냈다. 명확하고 상세한 답변을 해주셔서 감사합니다. 각도 문서화에 대한 링크를 얻을 수있는 기회가 있습니까? - eagle.dan.1349
  • 나는이 답변에서 당신이 어떤 종류의 연결을 기대하고 있는지 확실히 모르겠다. - Marcus Riemer
  • 이 답변은 plunkr을 포함하면 훌륭합니다. - Zze

28

나는 똑같은 문제가 있었다.

여기에 대한 대답은 loadChildren을 사용하면 꽤 좋다.

          {
             path: 'mypath',
             loadChildren : () => myModule
          }

https://github.com/angular/angular/issues/10958


  • 이건 작동하지 않습니다 .... - mp3por
  • 그것은 나를 위해 일합니다! - Alex Klaus
  • 이 링크는 특히 유용합니다. - Zze
  • 좋아. @ mp3por 그것은 RC6에서 작동합니다. - Sarat Chandra

1

이 문제를 해결할 방법을 찾았습니다. 근본적으로, 저는 이전에 사용하던 방식대로 경로를 정의하고 있지만 이번에는 상위 수준의 자식 수준으로 정의합니다. 예를 들어 내 관리 경로 :

const AdminRoutes: Routes = [
   {
      path: 'admin',
      component: AdminComponent,
      children: [
          ...setupRoutes
      ]
   }
]

export const adminRouting = RouterModule.forChild(AdminRoutes)

내 설정 경로 파일은 더 많은 하위 항목을 포함하여 자신의 경로를 정의하는 하위 영역에서 가져옵니다. catch는이 파일이 RouterModule.forChild 결과가 아닌 "Routes"객체를 내 보냅니다.

설치가 끝나면 하위 모듈 정의에서 하위 및 하위 하위 경로를 제거했습니다. 그런 다음 위에서 언급 한 Marcus처럼 각 서브 모듈의 경로에 사용 된 모든 구성 요소를 내 보내야했습니다. 일단 내가 그랬 으면, 나는 그들이 원했던 것처럼 일하기 시작했다.

부모 모듈은 자식 모듈 경로에 대해 너무 많이 알고 있기 때문에 나는이 솔루션을 정말 좋아하지 않는다고 생각합니다. 그러나 적어도 RC5를 위해 그 주위를 둘러 볼 수있는 쉬운 방법은 모든 곳의 모든 부품을 새어 나가는 것이 아닙니다. 그가 나를 올바른 길로 인도하기 때문에 나는 마커스의 답을 답으로 표시 할 것이다.


  • 이 작품은 나를 위해, 감사합니다! - Alex G
  • 안녕하세요 John, 접근 방식이 효과적이지만 모듈 지연로드를 어떻게 처리합니까? 이 방법을 사용하면 다른 모듈을 게으른로드 할 수 없습니다. - Alex G

1

나는 2.0.0 rc5가 지금 관심이 없다고 생각한다. 그러나 앵귤러 4에서 일하고 있으며, 초기일지도 모릅니다.

@NgModule({
    imports: [
        RouterModule.forRoot([
                {path: "", redirectTo: "test-sample", pathMatch: "full"},
                {
                    path: "test-sample",
                    loadChildren: () => TestSampleModule
                }
        ])
    ],
    exports: [RouterModule],
    declarations: [] 
}) 
export class AppRoutingModule{}

@NgModule({
    imports: [
        RouterModule.forChild([{
                    path: "",
                    component: TestSampleComponent,
                    children: [
                        {path: "", redirectTo: "home", pathMatch: "full"},
                        {
                            path: "home",
                            loadChildren: () => HomeModule
                        },
                        {
                            path: "about",
                            loadChildren: () => AboutModule
                        }
                    ]
                }
        ])
    ],
    exports: [RouterModule],
    declarations: []
})
export class TestSampleRoutingModule {}

@NgModule({
    imports: [RouterModule.forChild([{
                    path: "",
                    component: AboutComponent
                }
    ])],
    exports: [RouterModule]
})
export class AboutRoutingModule {}

다음을 고려하십시오.loadChildren: () => {...}. 게으른로드가 아닙니다.

세부 사항보기feat : NgModules 계층 지원 ss 지연로드


0

ngModules 및 RC5를 사용하는 경우 상위 모듈의 라우팅 구성에서 하위 모듈 라우팅에 대해 알 필요가 없습니다. 상위 모듈의 경로는 여기에서 정의해야합니다. 또한 하위 모듈을 상위 모듈로 가져와야합니다. 하위 모듈에서는 다음과 같이 경로를 정의해야합니다.

export const childRoutes: Routes = [
  {
    path: 'someChild',
      component: SomeChildComponent,
      children: [
        { path: '', component: SomeChildSubComponent1 },
        { path: 'comp1', component: SomeChildSubComponent1 },
        { path: 'comp2', component: SomeChildSubComponent2 }
      ]
  }
];

이렇게하면 / someParent / someChild / comp1과 같은 URL을 가질 수 있으며 구성 요소는 해당 라우터 출력에 표시됩니다. 참고 : 빈 경로에 대한 구성 요소를 선언해야합니다. 그렇지 않으면 자녀에게 네비게이션 할 수 없습니다.


  • 이는 중첩의 첫 단계에서만 작동합니다. 모든 후속 레벨에서 루트는 루트 모듈에 추가되고 부모를 통해 도달 할 수 없습니다. - Thorsten Westheider
  • 높은 Torsten, 불행히도 당신 말이 맞아. 부모 경로를 추가하여 경로 객체의 경로 정보를 수정할 때 구성 요소에 접근 할 수 있습니다. 하지만 여전히 올바른 라우터 콘센트에서는 볼 수 없습니다. 그것도 당신의 솔루션에 문제가있는 것 같습니다. 버그일까요? 이 문제가 이미 공개되어 있다면 알고 계십니까? - westor
  • 디자인 상으로는 느린 로딩을 사용하여 문제를 해결할 수 있습니다. & # 39; 어쨌든 아마도 더 나은 해결책 일 것입니다. - Thorsten Westheider
  • 이 문제에 대한 진전 사항은 무엇입니까? 방금 버전 2.0.0에서 같은 문제에 직면했습니다. @ThorstenWestheider - Kinorsi

0

나는이 작업을 잘 수행하고 실제로 계층 구조의 모든 상위 구성 요소를 렌더링해야하는 경우가 아니라면 내 솔루션이 훨씬 더 우아하다고 생각합니다.

나의 접근 방법을 이해하는 열쇠는 루트 모듈에 모듈을 얼마나 깊이 중첩 시켜도 모든 루트가 있다는 것입니다. 빠른 예를 들어 보겠습니다.DepartmentModule그리고EmployeeModule우리는이 URL을 사용하여 탐색하고자합니다.

/department/1/employee/2

어느 시점에서 직원 2의 세부 정보를 볼 수 있습니다. 경로 구성department...에서department.routing.tsemployee...에서employee.routing.ts의지아니우리가 의도 한 방식대로 작동하면 탐색 할 수 있음을 알게 될 것입니다.

/employee/2

루트 구성 요소에서

/department/1/employee/2

충돌이 발생합니다 (경로를 찾을 수 없음). 이 시나리오의 일반적인 경로 구성은 다음과 같습니다.

export const departmentRoutes: Routes = [
    { path: 'department', component: DepartmentComponent, children: [
        { path: '', component: DepartmentsComponent },
        { path: ':id', component: DepartmentDetailsComponent }
    ]}
];

export const employeeRoutes: Routes = [
    { path: 'employee', component: EmployeeComponent, children: [
        { path: '', component: EmployeesComponent },
        { path: ':id', component: EmployeeDetailsComponent }
    ]}
];

EmployeeModule에 의해 수입 될 것이다.DepartmentModule. 자, 내가 말했듯이, 그것은 불행하게도 작동하지 않습니다.

그러나 단 한 번의 변경으로 다음과 같이됩니다.

export const employeeRoutes: Routes = [
    { path: 'department/:id/employee', component: EmployeeComponent, children: [
        { path: '', component: EmployeesComponent },
        { path: ':id', component: EmployeeDetailsComponent }
    ]}
];

그 잡기는DepartmentModule더 이상 탐색하지 않으면 더 이상 활발한 역할을하지 않습니다.employeeURL을 사용할 수 있지만 여전히 모든 매개 변수에 액세스 할 수 있습니다.ActivatedRoute:

export class EmployeeDetailsComponent {
    departmentId: number;
    employeeId: number;
    constructor(route: ActivatedRoute) {
        route.parent.params.subscribe(params =>
            this.departmentId= +params['id'])
        route.params.subscribe(params => 
            this.employeeId= +params['id']);
    }
}

이것이 공식적인 접근 방법이되어 줄 수 있을지 궁금하지만, 지금은 Angular 2 팀의 차기 변경이있을 때까지이 점이 저에게 효과적입니다.


0

용도loadChildren. 괜찮아. 그러나 빌드 프로세스를 다시 시작하면 빌드 오류가 발생합니다. 내 보낸 기호를loadChildren.

import { ChildModule } from './child/child.module';

export function childRouteFactory() {
  return ChildModule;
}

...
  {
    path: 'child',
    loadChildren: childRouteFactory
  }
...

연결된 질문


관련된 질문

최근 질문