JavaRush /Курсы /Модуль 4: Node.js, Next.js и Angular /<router-outlet>: отображение компонентов маршрутов

<router-outlet>: отображение компонентов маршрутов

Модуль 4: Node.js, Next.js и Angular
18 уровень , 2 лекция
Открыта

1. Знакомство с <router-outlet>

Если маршруты — это карта, по которой Angular определяет, какой компонент показать для каждого URL, то <router-outlet> — это «окно», в которое Angular подгружает нужный компонент. Можно сказать, что <router-outlet> — это телепорт для ваших компонентов: куда Angular «приземляет» компонент, соответствующий текущему маршруту.

Аналогия:
Представьте себе многоэтажный дом, где в каждой квартире живёт свой компонент. <router-outlet> — это дверь, через которую в квартиру входит тот, кто соответствует текущему адресу (URL). Если адрес изменился — Angular «выгоняет» одного жильца и заводит нового.

Без <router-outlet> Angular просто не знает, куда вставлять компоненты маршрутов! Даже если маршруты настроены идеально, если в шаблоне нет <router-outlet>, компоненты маршрутов не появятся на экране.

Как работает <router-outlet>

Когда Angular стартует приложение, он ищет в шаблоне компонент, куда он может «вставить» компонент маршрута. Обычно <router-outlet> располагают в корневом компоненте приложения (AppComponent). Когда пользователь переходит по ссылке или меняется URL, Angular:

  1. Сравнивает URL с определёнными маршрутами.
  2. Находит компонент, который должен быть отображён.
  3. Вставляет этот компонент внутрь <router-outlet>.

Схема работы:

flowchart TD
    A[Маршрут: /about] --> B[Компонент AboutComponent]
    B --> C[<router-outlet> в шаблоне]
    C --> D[Отображение на странице]
  
Визуализация работы <router-outlet>

2. Практический пример: базовое приложение с маршрутизацией

Шаг 1. Настроим маршруты

Допустим, у нас есть два компонента: HomeComponent и AboutComponent. Мы хотим показывать их на разных маршрутах:


// app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';

const routes: Routes = [
  { path: '', component: HomeComponent }, // Главная страница
  { path: 'about', component: AboutComponent } // О нас
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Шаг 2. Используем <router-outlet> в шаблоне

В app.component.html (или любом другом компоненте, где вы хотите отображать маршруты):


<!-- app.component.html -->
<h1>Моё Angular-приложение</h1>
<nav>
  <a routerLink="/">Главная</a> |
  <a routerLink="/about">О нас</a>
</nav>
<hr>
<router-outlet></router-outlet>

Что происходит:
— При переходе по ссылке «Главная» (/), в <router-outlet> появится содержимое HomeComponent.
— При переходе по «О нас» (/about), в <router-outlet> появится AboutComponent.

Шаг 3. Примеры компонентов


// home.component.ts
import { Component } from '@angular/core';
@Component({
  selector: 'app-home',
  template: `<h2>Добро пожаловать на главную!</h2>`
})
export class HomeComponent { }

// about.component.ts
import { Component } from '@angular/core';
@Component({
  selector: 'app-about',
  template: `<h2>О нас: мы любим Angular!</h2>`
})
export class AboutComponent { }

Результат:
В зависимости от активного маршрута в <router-outlet> будет отображаться соответствующий компонент.

3. Можно ли использовать несколько <router-outlet>?

Да, и это не баг, а фича! В Angular можно вставлять несколько <router-outlet> в разные части шаблона. Это используется для вложенных маршрутов (child routes) и для параллельных маршрутов. Но если вы только начинаете, не спешите усложнять жизнь — один <router-outlet> в корневом компоненте покрывает 99% задач новичка.

Пример вложенных маршрутов:


const routes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'about', component: AboutComponent, children: [
      { path: 'team', component: TeamComponent }
    ]
  }
];

В шаблоне AboutComponent:


<!-- about.component.html -->
<h2>О нас</h2>
<router-outlet></router-outlet> <!-- Здесь появится TeamComponent при маршруте /about/team -->

4. Полезные нюансы

Как Angular решает, куда вставлять компонент?

Angular всегда ищет ближайший подходящий <router-outlet>, начиная с корневого компонента. Если маршрут простой (без вложенности), то компонент попадёт в <router-outlet> в AppComponent. Если маршрут вложенный, то дочерний компонент попадёт в <router-outlet> внутри родительского компонента.

graph TD
    A[AppComponent] -->|<router-outlet>| B[AboutComponent]
    B -->|<router-outlet>| C[TeamComponent]
  
Вложенные <router-outlet> для вложенных маршрутов

Советы по размещению <router-outlet>

  • Обычно размещайте <router-outlet> там, где должен меняться основной контент страницы.
  • Всё, что написано до/после <router-outlet>, будет всегда видно (например, меню, футер).
  • Можно стилизовать <router-outlet> через обёртку, если нужно добавить отступы, фон и пр.

Пример:


<header>Меню</header>
<main>
  <router-outlet></router-outlet>
</main>
<footer>Подвал</footer>

Как работает <router-outlet> за кулисами

Если вы любите смотреть под капот, знайте: <router-outlet> — это Angular-директива, которая слушает сервис маршрутизации и динамически создает нужный компонент, когда меняется маршрут. Angular не просто вставляет HTML, а реально создаёт экземпляр компонента, с жизненным циклом, зависимостями и т.д.

5. Интерактивная практика: добавим третий маршрут

Давайте добавим страницу «Контакты» и убедимся, что всё работает.

  1. Создайте компонент:
    ng generate component contacts
  2. Добавьте маршрут:
    
    // app-routing.module.ts
    { path: 'contacts', component: ContactsComponent }
    
  3. Добавьте ссылку в меню:
    <a routerLink="/contacts">Контакты</a>
  4. В шаблоне компонента:
    
    <!-- contacts.component.html -->
    <h2>Свяжитесь с нами!</h2>
    <p>Email: hello@example.com</p>
    

Теперь при переходе по /contacts в <router-outlet> появится ContactsComponent.
Магия? Нет, просто Angular и <router-outlet>!

6. Типичные ошибки при работе с <router-outlet>

Ошибка №1: Забыли добавить <router-outlet> в шаблон.
Самая частая проблема. Вы настроили маршруты, переходите по ссылкам — а на экране ничего не меняется. Почему? Потому что Angular не знает, куда вставлять компонент маршрута. Добавьте <router-outlet> — и всё заработает.

Ошибка №2: Несколько <router-outlet>, но маршруты не вложенные.
Если у вас несколько <router-outlet>, но маршруты не вложены или не настроены правильно, Angular не сможет понять, какой компонент куда вставлять. В результате — пустые места или неожиданные ошибки.

Ошибка №3: Путают <router-outlet> с селекторами компонентов.
Иногда новички пытаются вставить компонент маршрута через его селектор (<app-home></app-home>), а не через <router-outlet>. Это не будет работать с маршрутизацией — компонент просто всегда будет на странице, независимо от маршрута.

Ошибка №4: Нет импорта RouterModule
Если забыли импортировать RouterModule в модуль, где используете <router-outlet>, получите ошибку «Can't bind to 'routerLink' since it isn't a known property» или «'router-outlet' is not a known element». Проверьте импорты!

Ошибка №5: Стилизация <router-outlet>
Иногда пытаются стилизовать сам <router-outlet>, забывая, что это не визуальный элемент, а директива. Стилизовать нужно обёртку вокруг него.

Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ