angularroutesangular-ui-routerbootstrap-5

Angular & Bootstrap - Routes


I have created a menu, breadcrumbs, with components and their children. The problem is that I see the first child perfectly with but when I open a child of that child (grandchildren so to speak) the component opens under its parent. My goal is to remove the parent's view and show only the child's. I leave code for better understanding. The father is casilleros.component and his child is historial.component

<!-- dashboard.component.html -->
<div class="dashboard-container">
    <app-menu></app-menu>
    <div class="content-area">
        <app-navbar></app-navbar>
        <app-breadcrumb></app-breadcrumb>
        <div class="dashboard-content">
            <router-outlet></router-outlet>
        </div>
    </div>
</div>
// app-routing.module.ts
const routes: Routes = [
  { path: '', redirectTo: 'login', pathMatch: 'full' },
  { path: 'login', component: LoginComponent },
  { path: 'navbar', component: NavbarComponent },
  {
    path: 'dashboard', component: DashboardComponent, data: { breadcrumb: 'Dashboard' },
    children: [
      { path: 'permisos', component: PermisosComponent, data: { breadcrumb: 'Permisos' }},
      { path: 'operarios', component: OperariosComponent, data: { breadcrumb: 'Operarios' }},
      { path: 'maquinas', component: MaquinasComponent, data: { breadcrumb: 'Máquinas' }},
      { path: 'materiales', component: MaterialesComponent, data: { breadcrumb: 'Materiales' }},
      { 
        path: 'casilleros', component: CasillerosComponent, data: { breadcrumb: 'Casilleros' },
        children: [
          { path: 'historial', component: HistorialComponent, data: { breadcrumb: 'Historial' }, outlet: 'casilleros' }
        ]
      },
--
--
--

    <!-- casilleros.component.html -->
    <div class="container mt-4">
        <div class="d-flex justify-content-between mb-3">
            <input type="text" class="form-control w-50" placeholder="Buscar">
        </div>
        <table class="table table-striped">
            <thead>
                <tr>
                    <th></th>
                    <th>Referencia</th>
                    <th>Ubicación</th>
                    <th>Activo</th>
                    <th>Ocupado</th>
                    <th>Acción</th>
                </tr>
            </thead>
            <tbody>
                <tr *ngFor="let item of items; let i = index;">
                    <td>{{i}}</td>
                    <td>{{ item.referencia }}</td>
                    <td>{{ item.ubicacion }}</td>
                    <td>
                        <div class="form-check form-switch">
                            <input class="form-check-input" type="checkbox" id="activo{{ item.referencia }}" checked>
                        </div>
                    </td>
                    <td>
                        <div class="form-check form-switch">
                            <input class="form-check-input" type="checkbox" id="ocupado{{ item.referencia }}" checked>
                        </div>
                    </td>
                    <td>
                        <button (click)="goToHistorial(item)" class="btn btn-sm"><i class="bi bi-search"></i></button>
                        <button class="btn btn-sm"><i class="bi bi-pencil"></i></button>
                        <button class="btn btn-sm"><i class="bi bi-trash"></i></button>
                    </td>
                </tr>
            </tbody>
        </table>
        <router-outlet name="casilleros"></router-outlet>
    </div>

import { Component } from '@angular/core';
import { Router } from '@angular/router';

@Component({
  selector: 'app-casilleros',
  templateUrl: './casilleros.component.html',
  styleUrls: ['./casilleros.component.css']
})
export class CasillerosComponent {

  constructor(private router: Router) {}

  items = [
    { referencia: 101, ubicacion: 'Vinilo' },
    { referencia: 102, ubicacion: 'Vinilo' },
    { referencia: 103, ubicacion: 'Vinilo' },
    { referencia: 104, ubicacion: 'Vinilo' },
    { referencia: 105, ubicacion: 'Vinilo' },
    { referencia: 106, ubicacion: 'Vinilo' },
    { referencia: 107, ubicacion: 'Vinilo' },
    { referencia: 108, ubicacion: 'Vinilo' },
    { referencia: 109, ubicacion: 'Vinilo' },
    { referencia: 110, ubicacion: 'Vinilo' }
  ];

  goToHistorial(item: any) {
     this.router.navigate([{ outlets: { casilleros: ['historial'] } }]);
  }
}

Solution

  • If i understand you correctly. Your problem lies in the structure of your routing and how you manage the display of child components within your angular application.

    Do the following step.

    1. Remove the named router from casilleros.component.html
    2. Adapt the navigation in your casilleros.component.ts
    import { Component } from '@angular/core';
    import { Router } from '@angular/router';
    
    @Component({
      selector: 'app-casilleros',
      templateUrl: './casilleros.component.html',
      styleUrls: ['./casilleros.component.css']
    })
    export class CasillerosComponent {
    
      constructor(private router: Router) {}
    
      goToHistorial(item: any) {
         this.router.navigate(['dashboard/casilleros/historial']);
      }
    }
    

    Update

    I created a stackblitz to better understand your problem.

    When you nest routes, the child component is rendered within the parent's router-outlet, causing both views to display together.

    To display HistorialComponent when navigating from CasillerosComponent, restructure your routes so that HistorialComponent replaces the parent view (CasillerosComponent), instead of rendering within it.

    Do the following step.

    1. Adapt routes: Move HistorialComponent within the same level of CasillerosComponent
    const routes: Routes = [
      { path: '', redirectTo: 'login', pathMatch: 'full' },
      { path: 'login', component: LoginComponent },
      { path: 'navbar', component: NavbarComponent },
      {
        path: 'dashboard', component: DashboardComponent, data: { breadcrumb: 'Dashboard' },
        children: [
          { path: 'permisos', component: PermisosComponent, data: { breadcrumb: 'Permisos' }},
          { path: 'operarios', component: OperariosComponent, data: { breadcrumb: 'Operarios' }},
          { path: 'maquinas', component: MaquinasComponent, data: { breadcrumb: 'Máquinas' }},
          { path: 'materiales', component: MaterialesComponent, data: { breadcrumb: 'Materiales' }},
          { path: 'casilleros', component: CasillerosComponent, data: { breadcrumb: 'Casilleros' },},
          { path: 'historial', component: HistorialComponent, data: { breadcrumb: 'Historial' },},
        ],
      },
    ];
    
    
    1. Remove the named router from casilleros.component.html
    2. Adapt the navigation in your casilleros.component.ts
        this.router.navigate(['dashboard/historial']);