Динамические компоненты в Angular позволяют загружать компоненты во время выполнения в тех случаях, когда во время сборки вы не знаете, какой компонент необходимо отрисовать.

Например, в обычном случае списка/элемента у вас будет ListComponent, в котором вы будете отображать ItemComponent для каждого элемента в вашем списке, используя директиву *ngFor. Это работает, если вы знаете, как должен отображаться каждый элемент в списке.

Возьмем глупый, но конкретный пример. У вас есть список домашних животных. Кто-то собаки, кто-то кошки. Кошки и собаки имеют разные атрибуты и должны рендериться по-разному, и вы, конечно, не знаете заранее, как будет выглядеть список питомцев, возвращаемый сервером. Одним из решений этой проблемы является использование динамических компонентов.

Я уже писал об этом статью в Angular 8. С тех пор процесс упростился, давайте обновим пример.

Если у вас есть кошки и собаки, реализующие общий интерфейс Pet:

export default interface Pet {
  name: string;
  age: number;
  profilePicture?: string;
}
import Pet from './Pet';

export default interface Dog extends Pet {
  favoritePark: string;
}
import Pet from './Pet';

export default interface Cat extends Pet {
  favoriteComfyPlace: string;
}

возможно, вы захотите изобразить кошек с их любимым удобным местом:

<div class="card">
  <img [src]="member.profilePicture || 'assets/cat.png'"/>
  <div class="info">
    <div class="name">{{member.name}}</div>
    <div class="age">Age: {{member.age}}</div>
    <div class="favorite-comfy-place">Favorite Comfy Place: {{member.favoriteComfyPlace}}</div>
  </div>
</div>

а мы хотим отобразить собак с их любимым парком:

<div class="card">
  <img [src]="member.profilePicture || 'assets/dog.png'" />
  <div class="info">
    <div class="name">{{member.name}}</div>
    <div class="age">Age: {{member.age}}</div>
    <div class="favorite-park">Favorite Park: {{member.favoritePark}}</div>
  </div>
</div>

чтобы в итоге получить список участников, похожий на этот: