Search code examples
angulartypescriptlazy-loadingangular-routing

How to prevent the common layout/shell component to be destroyed when lazy loading a module?


Consider the following two modules -

  • Public module - contains Home, about, etc components
  • Private module - contains Profile, Settings, etc components

All these components use a shared shell/layout MainShellComponent which is configured in app-routing.module as -

const routes: Routes = [
    {
        path: '',
        component: MainShellComponent,
        children: [
            { path: 'about', component: AboutComponent },
            { path: 'profile', component: ProfileComponent },
            { path: 'settings', component: SettingsComponent },
            { path: '', component: HomeComponent },
            { path: 'home', redirectTo: '', pathMatch: 'full' }
            { path: '**', component: PageNotFoundComponent }
        ]
    }
];

I wanted to configure the Private module to lazy load. So I changed the code in app-routing.module -

const routes: Routes = [
    {
        path: '',
        component: MainShellComponent,
        children: [
            { path: 'about', component: AboutComponent },
            { path: '', component: HomeComponent },
            { path: 'home', redirectTo: '', pathMatch: 'full' }         
        ]
    },
    {
        path: 'user',
        component: MainShellComponent,
        loadChildren: './private/private.module#PrivateModule'
    },
    { path: '**', component: PageNotFoundComponent }
];

and in private-routing.module -

const routes: Routes = [
    { path: 'profile', component: ProfileComponent },
    { path: 'settings', component: SettingsComponent }
];

Now the Private module is loading lazily but the MainShellComponent is being destroyed and re-constructed for the components in the Private module, and I understand that it is exactly what is supposed to happen under the current route configuration.

I want -

  1. the Public module to be loaded normally(eagerly)
  2. the Private module to be loaded lazily
  3. the MainShellComponent not to be destroyed and re-constructed

So, how can I achieve this?


Solution

  • Leave everything as a child of the shell component:

    const routes: Routes = [
        {
            path: '',
            component: MainShellComponent,
            children: [
                { path: 'about', component: AboutComponent },
                { path: '', component: HomeComponent },
                { path: 'home', redirectTo: '', pathMatch: 'full' },
                { path: 'user', loadChildren: './private/private.module#PrivateModule' },
                { path: '**', component: PageNotFoundComponent }
            ]
        }
    ];