Development Tip

모듈의 자식으로 모듈에 라우팅하는 방법-Angular 2 RC 5

yourdevel 2020. 12. 1. 19:49
반응형

모듈의 자식으로 모듈에 라우팅하는 방법-Angular 2 RC 5


작업중인 애플리케이션을 최신 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",

내 앱은 여러 모듈이 상위 모듈의 자식으로 함께 붙어있는 모듈의 구성으로 빌드됩니다. 예를 들어 알림 모듈, 사용자 모듈 및 전화 통신 모듈 (예 :)로 구성된 관리 모듈이 있습니다. 이 모듈에 대한 경로는 다음과 같아야합니다.

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

라우터의 이전 릴리스에서는 "하위"를 사용하여 쉽게 수행 할 수있었습니다.

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

또한 이로 인해 새 사용자 구성 요소가 내 관리 구성 요소의 라우터 콘센트에로드되지 않아 내 응용 프로그램의 스타일과 탐색을 방해합니다.

내 UserModule의 경로를 AdminModule의 자식으로 참조하는 방법을 생각할 수는 없습니다. 나는 이것을 옛날 방식으로 시도했고 두 개의 모듈에있는 경로에 대한 오류를 얻었습니다. 분명히 이것이 새로 출시 되었기 때문에 이러한 사례 중 일부에 대한 문서는 약간 제한적입니다.

누구든지 제공 할 수있는 어떤 도움이라도 대단히 감사하겠습니다!


좋아, 주말의 더 나은 부분을 위해 이것 저것 만지작 거리고 난 후에 나는 그것을 내 끝에서 실행시켰다. 결국 나를 위해 일한 것은 다음을 수행하는 것이 었습니다.

  • 모든 내보내기 Routes당신이 경로에 원하는 모든 모듈. RouterModule.forChild()하위 모듈의 어떤 것도 가져 오지 마십시오 .
  • 내보내기 모든 차일 모듈 정의 차일 경로 정의에서 볼 수 구성 요소를.
  • import모든 하위 경로를 평소와 같이 가져오고 (Typescript 키워드 의미 ) ...연산자를 사용 하여 올바른 경로 아래에 통합합니다. 경로를 정의하는 자식 모듈과 함께 작동하도록 할 수는 없지만 부모에서 잘 작동하며 지연로드와 호환됩니다.

제 경우에는 다음과 같은 계층 구조에 세 가지 수준이 있습니다.

  • 루트 ( /)
    • 편집자 ( 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수입에 대한 요구 내보내기 QueryEditorQueryEditor수출에 대한 요구 QueryCreateComponentQueryEditorComponent이들과 같은 가져 오기에 볼 수 있습니다. 이 작업을 수행하지 않으면 Component XYZ is defined in multiple modules.

지연로드는이 설정에서도 잘 작동합니다.이 경우 자식 경로는 물론 가져 오지 않아야합니다.


나는 같은 문제가 있었다.

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

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

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


2.0.0 rc5는 지금 관심이 없다고 생각합니다. 그러나 Angular 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 계층 구조 지원


I found a way to resolve this as well. Basically, I am defining my routes the way that I used to, but this time at the top child level. For example my admin route:

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

export const adminRouting = RouterModule.forChild(AdminRoutes)

My setup routes file is imported from a sub area, which defines routes of it's own, including more children. The catch is that this file exports the "Routes" object and not the RouterModule.forChild result.

After that is setup, I removed the child and sub-child routes from the submodule definitions. I then had to export all of the components used in the routes, from each of the submodules, just like Marcus mentioned above. Once I did that, the routes started working just like I wanted them to.

I don't think I really like this solution since my parent module knows too much about the child module routes. But at least its an easy way to get around it for RC5, and it doesn't leak all of my components all over the place. I'll go ahead and mark Marcus' answer as the answer since he put me on the right track.


When you are using ngModules and RC5, the routing configuration of your parent module does not need to know anything about the child modules routing. You only have to define the routes for your parent module here. Furthermore you have to import the child module into your parent module. In the child module you have to define your routes this way:

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

This will let you have a url like /someParent/someChild/comp1 - and the components are displayed in their corresponding router-outlet. Please note: You HAVE TO declace a component for the empty path. Otherwise you are not able to navigate to you children.


I got this to work as well and unless you actually need to render all parent components in the hierarchy I think my solution is far more elegant.

The key to understanding my approach is that all routes, no matter how deeply nested in modules are added to the root module. Quick example, let's say we have a DepartmentModule and an EmployeeModule which we'd like to navigate to using this URL

/department/1/employee/2

at which point we'd see employee 2's details. Configuring routes for department in department.routing.ts and employee in employee.routing.ts will not work the way we intended and you'll notice that you can navigate to

/employee/2

from the root component, while

/department/1/employee/2

will crash (route not found). A typical route configuration in this scenario would look like this:

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

and EmployeeModule would be imported by DepartmentModule. Now, like I said, that doesn't work unfortunately.

However, with just a single change it will:

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

The catch is, that DepartmentModule is not taking an active part anymore as soon you navigate to an employee URL, but you still can access every parameter from the 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']);
    }
}

I wonder if this is supposed to be the official approach, but for now this works for me until the next breaking change from the Angular 2 team .


Use loadChildren. That's OK. But when you restart the build process, you will get the build error. You should match the exported symbol to the loadChildren.

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

export function childRouteFactory() {
  return ChildModule;
}

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

참고URL : https://stackoverflow.com/questions/38879529/how-to-route-to-a-module-as-a-child-of-a-module-angular-2-rc-5

반응형