Organizar una aplicación Angular de forma escalable requiere separar responsabilidades desde la estructura de carpetas hasta la configuración de rutas. Las vistas anidadas son la técnica que permite asignar layouts distintos a cada módulo, evitando que elementos como el menú de navegación se impongan de forma global en toda la aplicación.
¿Por qué separar la aplicación en módulos con su propio layout?
Cuando una aplicación crece, mantener un único app-navbar fijo en el app.component limita la flexibilidad. Cualquier sección nueva —un panel de administración, una página de login— heredaría ese header aunque no lo necesite. La solución es crear módulos independientes, cada uno con su propia estructura visual.
El primer paso consiste en crear una carpeta llamada website [01:07] y mover allí todo lo que pertenece exclusivamente al sitio público:
- Componentes propios del sitio web.
- Directivas específicas del módulo.
- Páginas como home, login, register y profile.
- Pipes utilizados en las vistas del website.
Los elementos que funcionan de forma global se quedan fuera del módulo. Los interceptores corren a nivel de toda la aplicación, los modelos pueden ser reutilizados por otros módulos y los servicios con providedIn: 'root' siempre tienen alcance global [01:37].
¿Cómo corregir las importaciones después de mover carpetas?
Al reorganizar carpetas, Visual Studio Code actualiza automáticamente muchas rutas de importación, pero no todas. La estrategia más confiable es detener el servidor de desarrollo, ejecutar ng serve de nuevo y revisar cada error que el compilador reporte [03:03]. Así se recorren archivo por archivo las importaciones rotas hasta que la compilación sea exitosa.
¿Qué es el componente layout y para qué sirve?
Una vez que el proyecto compila correctamente, se genera un nuevo componente dentro de website/components llamado layout [05:05]:
bash
ng generate component website/components/layout
Este componente reemplaza la estructura que antes vivía en app.component. En lugar de tener el app-navbar y el router-outlet en el componente raíz, ahora el app.component queda reducido a una sola línea con un <router-outlet> limpio [07:15].
El HTML del layout contiene:
html
<app-nav></app-nav>
<router-outlet></router-outlet>
De esta forma, solo las páginas hijas del módulo website heredan el menú de navegación y la maquetación definida en el layout.
¿Cómo configurar rutas con vistas anidadas en Angular?
La clave está en la propiedad children del objeto de ruta. En el archivo de routing se importa el LayoutComponent y se define como componente principal del path raíz [06:10]:
typescript
import { LayoutComponent } from './website/components/layout/layout.component';
const routes: Routes = [
{
path: '',
component: LayoutComponent,
children: [
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
{ path: 'login', component: LoginComponent },
{ path: 'register', component: RegisterComponent },
{ path: 'profile', component: ProfileComponent },
// más rutas del website
]
},
{ path: '**', component: NotFoundComponent }
];
La ruta not-found permanece fuera del layout porque debe funcionar para toda la aplicación, sin importar el módulo [06:48].
¿Qué significa que una página sea "hija" del layout?
Cada página declarada dentro del arreglo children se renderiza en el <router-outlet> interno del layout, no en el de app.component. Esto produce un esquema jerárquico que se puede verificar con las Angular DevTools del navegador [08:20]:
AppComponent → router-outlet principal.
LayoutComponent → app-nav + router-outlet interno.
- Página activa (home, login, etc.).
¿Qué ventajas ofrece esta arquitectura modular?
Con las vistas anidadas implementadas, la aplicación queda preparada para agregar nuevos módulos con layouts completamente diferentes. Un módulo de administración (CMS), por ejemplo, podría tener su propio menú lateral sin afectar al sitio público [08:52].
- Encapsulamiento: cada módulo controla su estructura visual.
- Escalabilidad: agregar secciones nuevas no modifica el componente raíz.
- Reutilización: servicios y modelos globales siguen disponibles para cualquier módulo.
Esta separación es el paso previo a la programación modular completa en Angular, donde cada módulo puede incluso cargarse de forma diferida con lazy loading. Si ya aplicas esta técnica en tus proyectos o tienes dudas sobre cómo extenderla, comparte tu experiencia en los comentarios.