5

I have an angular application where my main routing module lazy loads modules correctly. I do however now have an additional requirement of displaying another component / module inside one of the lazy loaded modules.

When I now navigate to users/id (this part works correctly) I want a tab view in the HTML where I can load additional modules based on what tab is clicked on. For example, I might have 3 buttons: User Albums, User Favourites and User Stats. When I click on one of those, I want a component to display on the same page as a child using the <router-outlet></router-outlet>

App Routing Module

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  { path: 'login',                 loadChildren: '../app/login/login.module#LoginModule' },
  { path: 'users',                 loadChildren: '../app/users/users.module#UsersModule' },
  { path: 'users/:id',             loadChildren: '../app/user-detail/user-detail.module#UserDetailModule' },
  { path: '',                      loadChildren: '../app/login/login.module#LoginModule', pathMatch: 'full' },
  { path: '**',                    loadChildren: '../app/login/login.module#LoginModule', pathMatch: 'full' },
];

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

user-detail.module

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { UserDetailComponent } from './user-detail.component';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  {
    path: '',
    component: UserDetailComponent,
    children: [
      {
        path: 'useralbums',
        loadChildren: '../user-albums/user-albums.module#UserAlbumsModule'
      },
    ]
  },
]


@NgModule({
  imports: [
    CommonModule,
    RouterModule.forChild(routes),
  ],
  declarations: [UserDetailComponent]
})
export class UserDetailModule { }

user-detail.html

<h1>User Detail</h1>
<a [routerLink]="['/users', user_id, 'useralbums']">User albums</a>
<a>Link Two</a>
<a>Link Three</a>
<router-outlet></router-outlet>

1 Answer 1

7

Since you want a new component to be loaded in case of a child route change and load it as a part of a lazy-loaded module, you can add a <router-outlet></router-outlet> to the template of the user-detail.component.html.

Something like this:

<h1>User Detail</h1>
<ul class="nav">
  <li class="nav-item">
    <a [routerLink]="['/users', user_id, 'user-albums']">User Albums</a>
  </li>
  <li class="nav-item">
    <a [routerLink]="['/users', user_id, 'user-favourites']">User Favourites</a>
  </li>
  <li class="nav-item">
    <a [routerLink]="['/users', user_id, 'user-stats']">User Stats</a>
  </li>
</ul>
<router-outlet></router-outlet>

Now, in the module of this file, define a route configuration to load the respective modules lazily:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Routes, RouterModule } from '@angular/router';

import { UserDetailComponent } from './user-detail.component';

const routes: Routes = [
  { 
    path: '', 
    component: UserDetailComponent,
    children: [
      {
        path: 'user-albums',
        loadChildren: './user-albums/user-albums.module#UserAlbumsModule'
      },
      {
        path: 'user-favourites',
        loadChildren: './user-favourites/user-favourites.module#UserFavouritesModule'
      },
      {
        path: 'user-stats',
        loadChildren: './user-stats/user-stats.module#UserStatsModule'
      },
    ]
  }
];

@NgModule({
  imports: [
    CommonModule,
    RouterModule.forChild(routes)
  ],
  declarations: [UserDetailComponent]
})
export class UserDetailModule { }

And then define the lazy modules with their configuration like this:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Routes, RouterModule } from '@angular/router';

import { UserAlbumsComponent } from './user-albums.component';

const routes: Routes = [
  { path: '**', component: UserAlbumsComponent }
];

@NgModule({
  imports: [
    CommonModule,
    RouterModule.forChild(routes)
  ],
  declarations: [UserAlbumsComponent]
})
export class UserAlbumsModule { }

PS: Since there are a lot of components, I'd suggest that you have a look at the solution stackblitz carefully in order to understand how the routing is wired in.


Here's a Working Sample StackBlitz for your ref.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.