Вложенные маршруты и ленивая загрузка
Вложенный (дочерний) маршрут показывает компонент внутри другой страницы: на странице статьи под текстом открываются комментарии по адресу /posts/1/comments. Ленивая загрузка (lazy loading) — когда код страницы скачивается только при первом переходе на неё, и приложение открывается быстрее.
Дочерние маршруты
Сначала добавьте в PostApi метод для комментариев и тип PostComment (импортируйте его в сервис из ./post-comment):
// src/app/post-api.ts
getComments(postId: number) {
return this.http.get<PostComment[]>(`${this.url}/${postId}/comments`);
}// src/app/post-comment.ts
export interface PostComment {
id: number;
postId: number;
name: string;
email: string;
body: string;
}Создайте компонент ng generate component post-comments и опишите его как дочерний маршрут в свойстве children:
// src/app/app.routes.ts
export const routes: Routes = [
{ path: 'posts', component: PostList },
{
path: 'posts/:id',
component: PostDetail,
children: [{ path: 'comments', component: PostComments }],
},
];Второй router-outlet
Дочерний компонент выводится в <router-outlet /> внутри родителя. Добавьте его в шаблон статьи вместе со ссылкой:
<!-- src/app/post-detail/post-detail.html -->
@if (post(); as p) {
<h2>{{ p.title }}</h2>
<p>{{ p.body }}</p>
<a routerLink="comments">Показать комментарии</a>
<router-outlet />
}Добавьте RouterOutlet в imports компонента PostDetail. Адрес без начального слеша в routerLink считается от текущей страницы: со страницы /posts/1 ссылка ведёт на /posts/1/comments.
Параметр родителя
Параметр id принадлежит родительскому маршруту, поэтому дочерний компонент берёт его у parent:
// src/app/post-comments/post-comments.ts
import { Component, inject } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { toSignal } from '@angular/core/rxjs-interop';
import { PostApi } from '../post-api';
@Component({
selector: 'app-post-comments',
template: `
@for (c of comments(); track c.id) {
<p><b>{{ c.email }}</b>: {{ c.body }}</p>
}
`,
})
export class PostComments {
private id = Number(inject(ActivatedRoute).parent?.snapshot.paramMap.get('id'));
comments = toSignal(inject(PostApi).getComments(this.id), { initialValue: [] });
}Нажмите «Показать комментарии» — под статьёй появятся пять комментариев, а адрес станет /posts/1/comments.
Ленивая загрузка компонента
Вместо component укажите loadComponent — функцию с динамическим import():
// src/app/app.routes.ts
{
path: 'todos',
loadComponent: () => import('./todo-list/todo-list').then((m) => m.TodoList),
},Уберите обычный import компонента TodoList в начале файла, иначе он всё равно попадёт в основной код. Команда ng serve покажет в терминале отдельный блок Lazy chunk files — это и есть код страницы, который скачается при переходе на /todos.
Ленивая группа маршрутов
Целый раздел с несколькими страницами выносят в свой файл маршрутов и подключают через loadChildren:
// src/app/admin/admin.routes.ts
import { Routes } from '@angular/router';
import { Dashboard } from './dashboard/dashboard';
export const adminRoutes: Routes = [
{ path: '', component: Dashboard },
];// src/app/app.routes.ts
{
path: 'admin',
loadChildren: () => import('./admin/admin.routes').then((m) => m.adminRoutes),
},Все страницы раздела /admin загрузятся одним куском при первом заходе.
Частая ошибка
Забыть <router-outlet /> в шаблоне родителя. Адрес меняется на /posts/1/comments, ошибок нет, но комментарии не появляются — дочернему компоненту некуда выводиться. Если у маршрута есть children, у его компонента должен быть свой router-outlet.