I can't understand the following behavior from angular routing.
I have just two components HomeTestComponent and CustomerComponent. When I press Home button followed by Customer button both components are displayed - I would expect only one component to be visible at a time?
This is my app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CustomerComponent } from './customer/customer.component';
import { HomeTestComponent } from './home-test/home-test.component';
const routes: Routes = [
{ path: 'customer', loadChildren: () => import('./customer/customer.module').then(m => m.CustomerModule) },
{ path: 'home', component: HomeTestComponent, outlet : "outlet2" }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
This is my app.component.html
<h1>
{{title}}
</h1>
<button type="button" [routerLink]="['customer', { outlets:{ outlet1: ['cust'] }} ]">Customer</button>
<button type="button" [routerLink]="['', { outlets:{ outlet2: ['home'] }}]">Home</button>
<router-outlet></router-outlet>
<div class="container">
<div class="row"><router-outlet name="outlet1"></router-outlet></div>
<div class="row"><router-outlet name="outlet2"></router-outlet></div>
</div>
and this is my customer-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CustomerComponent } from './customer.component';
const routes: Routes = [{ path: 'cust', component: CustomerComponent, outlet: "outlet1" }];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class CustomerRoutingModule { }
Modifications: If I make my home-test module lazy loading, then only one component is shown at a time - why (I would have expected two to be consistent)?
home-test-routing.module.ts:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeTestComponent } from './home-test.component';
const routes: Routes = [{ path: 'hom', component: HomeTestComponent, outlet: "outlet2" }];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class CustomerTestRoutingModule { }
app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CustomerComponent } from './customer/customer.component';
import { HomeTestComponent } from './home-test/home-test.component';
const routes: Routes = [
{ path: 'customer', loadChildren: () => import('./customer/customer.module').then(m => m.CustomerModule) },
{ path: 'home', loadChildren: () => import('./home-test/home-test.module').then(m => m.HomeTestModule)}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
app.component.html
<h1>
{{title}}
</h1>
<button type="button" [routerLink]="['customer', { outlets:{ outlet1: ['cust'] }} ]">Customer</button>
<button type="button" [routerLink]="['home', { outlets:{ outlet2: ['hom'] }}]">Home</button>
<router-outlet></router-outlet>
<div class="container">
<div class="row"><router-outlet name="outlet1"></router-outlet></div>
<div class="row"><router-outlet name="outlet2"></router-outlet></div>
</div>
It seems like you're using named router outlets in your Angular application. Named router outlets allow you to have multiple outlets in your application's layout where different components can be loaded simultaneously.
Let's go through your code to understand why both components are displayed when you press the Home button followed by the Customer button.
You have defined two routes: '/customer' which lazy loads the CustomerModule. '/home' which loads the HomeTestComponent into the named outlet 'outlet2'. The 'home' route is using a named outlet 'outlet2'. app.component.html:
You have two buttons: 'Customer' and 'Home'. Clicking the 'Customer' button sets the route to '/customer' and activates the 'cust' route within the 'outlet1' named outlet. Clicking the 'Home' button sets the route to '/' and activates the 'home' route within the 'outlet2' named outlet. customer-routing.module.ts:
Defines the route '/cust' which loads the CustomerComponent into the named outlet 'outlet1'.
When you press the 'Customer' button followed by the 'Home' button, both components are displayed because Angular is rendering components into both named outlets simultaneously.
If you want only one component to be visible at a time, you should reconsider the use of named outlets. If you intend to have two separate areas where components can be loaded, then named outlets are the correct approach. Otherwise, if you want to display only one component at a time, you can use the primary router outlet without naming it.
Here's how you can modify your code to achieve that:
Here's a modified version of your code:
app-routing.module.ts:
app.component.html:
With these modifications, only one component will be displayed at a time, depending on which button you click.
If you make home-test module lazy loading
When you make the
HomeTestModulelazy-loaded, you are changing how Angular loads and manages the components within that module. Lazy loading means that the module and its components are loaded only when they are needed, typically when the corresponding route is activated.In your original setup,
HomeTestComponentwas eagerly loaded as it was directly imported into theAppRoutingModule. With lazy loading,HomeTestComponentis no longer eagerly loaded. It is loaded only when the 'home' route is activated.Here's how the behavior changes when you make
HomeTestModulelazy-loaded:CustomerModuleis loaded into the named outlet 'outlet1', and theCustomerComponentis rendered.HomeTestModuleis loaded into the named outlet 'outlet2', and theHomeTestComponentis rendered, replacing whatever component was previously rendered in that outlet. Since named outlets are independent, theCustomerComponentremains visible in 'outlet1'.Because lazy loading delays the loading of the
HomeTestModuleuntil the 'home' route is activated, you see the behavior where only one component is displayed at a time. This behavior is consistent with Angular's lazy loading mechanism, which loads modules and their components dynamically based on the route configuration.