Kingmaker
Kingmaker

Reputation: 509

Split routes into separate modules in angular 6

I'm working on an Angular 6 application. Currently I'm struggling with routing. I'm interested, whether mine structure, what I have imagined can work or not. So it looks like this:

App module - contains main routing with some parent route, where layout is defined. Like this:

const routes: Routes = [
{
    path: 'login',
    component: LoginComponent
},
{
    path: '',
    component: LayoutComponent,
    canActivate: [AuthGuard],
    canActivateChild: [AuthGuard],
    children: [
    // {
    //   path: 'brands',
    //   loadChildren: 'app/modules/brands/brands.module#BrandsModule',
    //   pathMatch: 'prefix'
    // }
    ]
}
];

@NgModule({
    imports: [RouterModule.forRoot(routes), BrandsModule, ItemsModule],
    exports: [RouterModule],
    providers: [BosRouteLoader]
})
export class RoutingModule {}

One of mine feature module defines its own routing in a module like this:

const routes: Routes = [
{
    path: 'brands',
    children: [
    { path: '', component: BrandListComponent },
    { path: ':id', component: BrandDetailComponent },
    { path: '**', redirectTo: '' }
    ]
}];


@NgModule({
    imports: [RouterModule.forChild(routes)],
    exports: [RouterModule]
})
export class BrandsRoutingModule {}

I would like to achieve that every feature module will define its own routing and those routes are registered as a child routes of the App module.

With lazy loading I can manage it but then I have to define one more route always in mine App module, however I just want to define it in feature module.

If I do it without lazy loading, then mine parent route in App component is never hit. So if I go to http://localhost/brands it will load the appropriate BrandLisComponent but without LayoutComponent.

Is ther a way to define routes in feature module and register them as a child of main main routing module?

Upvotes: 3

Views: 6690

Answers (2)

Mikel Urkia
Mikel Urkia

Reputation: 2095

Imans77's answer works for lazy loaded modules (although the string from of LoadChildren is now deprecated). However, with eager loaded modules, if you want to tidy up the main routes module and split the file accross different modules, you could try the following approach:

app-routing.module.ts

const MODULE_ROUTES = [...module1Routes, module2Routes];

const routes: Routes = [

  { path: 'path1', component: Path1Component },
  { path: 'path2', component: Path2Component },
  ...MODULE_ROUTES,
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Instead of declaring all children of every component/module in the main routing file, you could create a *.route.ts file for each feature module, in which you could just declare and export routes in a normal way. For example:

export const module1Routes: Routes = [
{
    path: 'brands',
    children: [
        { path: '', component: BrandListComponent },
        { path: ':id', component: BrandDetailComponent },
        { path: '**', redirectTo: '' }
    ]
}];

By importing it in the main routing file, they would immediately be available for Angular.

Upvotes: 2

imans77
imans77

Reputation: 512

The concept is that you define a module routing in your higher-level module and then define its children in your desired module.

So in your case, you need to tell the angular that, hey when someone goes to brands route, use BrandsRoutingModule routings.

So in your app module, you're going to have:

{
    path: 'brands',
    loadChildren: 'app/modules/brands/brands.module#BrandsModule',
    canActivate: [AuthGuard],
    canActivateChild: [AuthGuard],
}

This tells that you need to load the routing of that module if the user goes to /brand.

Then in your BrandsRoutingModule, you need to define routes to be:

{
    path: '',
    component: LayoutComponent,
    children: [
        { path: '', redirectTo: 'home', pathMatch: 'full' },
        { path: 'home', component: BrandListComponent },
        { path: ':id', component: BrandDetailComponent },
        { path: '**', redirectTo: '' }
    ]
}

So whenever we route to /brands, we shall see the LayoutComponent as a main route relative to that and then the BrandListComponent and others will come as his children. But to show his children, you also need to put this line of code in your layout.component.html:

<router-outlet></router-outlet>

this tells angular that, hey if he's going to for example /brands/2, you need to load the BrandDetailComponent inside the LayoutComponent, literally as his child.

Hope it helps.

Upvotes: 5

Related Questions