В этой статье мы поговорим о создании компонентов динамически, шаг за шагом пройдем этот путь. Помимо простого создания компонентов, мы поговорим о более продвинутых вещах, которые можно сделать в рамках этого процесса. В первую очередь нам нужен сам компонент, который мы будем динамически создавать. Будем использовать простой компонент alert, который принимает тип оповещения как инпут свойство Стоит сказать, что динамические компоненты, а вернее те, которые создаются динамически, являются элементами DOM, и, соответственно, в шаблоне необходимо обеспечить место, куда его нужно добавить. В компоненте my-app создаем шаблон, используя тег ng-template и добавляем к нему переменную через #. Этот template как раз является местом, куда добавится компонент, дальше будем называть это контейнером. В роли контейнера может выступать любой компонент или элемент DOM. Теперь в компоненте нужно получить ссылку на контейнер. Это можно сделать с помощью ViewChild. Кстати, у меня уже есть статья, которая поможет разобраться в процессах, связанных с взаимодействием с DOM элементами, где как раз подробно рассказывается о декораторе ViewChild. Манипулируй DOM правильно. Дефолтное значение, которое возвращается из ViewChild, это экземпляр компонента или элемента DOM, но в нашем случае нужен ViewContainerRef. Название этого класса говорит само за себя, ViewContainerRef содержит в себе ссылку на контейнер, а также методы, которые позволяют создавать компоненты. Подготовим небольшой интерфейс для создания компонентов. Добавим на страницу две кнопки, а также заинжектим один сервис в наш компонент. Сервис ComponentFactoryResolver содержит метод resolveComponentFactory, который принимает в себя компонент, и возвращает ComponentFactory, в котором, в свою очередь присутствует метод create(), именно он и будет использоваться нашим контейнером для создания компонента.  Итак, теперь есть всё необходимое для метода, создающего компоненты. Давайте пройдемся по порядку и посмотрим, что тут происходит Каждый раз, когда мы нажмем кнопу для создания компонента, нам необходимо очистить контейнер от предыдущего представления. Иначе это будет подобно методу push() для массивов, что в данной ситуации не является хорошей практикой. resolveComponentFactory() принимает класс компонента и возвращает ComponentFactory, где есть всё необходимое чтобы его создать. Мы вызываем метод createComponent() и передаем переменную типа ComponentFactory. Под капотом этот метод вызывает create() и добавляет готовый компонент как дочерний в контейнер. После всех этих взаимодействий у нас есть ссылка на компонент, и мы можем установить значение его Input свойства Так же можно и подписаться на Output свойство компонента. Чтобы избежать утечек памяти, стоит уничтожить компонент после использования Метод для создания компонента готов, все операции изучены и понятны, и, в конце концов, остается только добавить динамический компонент в массив entryComponents в модуле. Ангуляр обеспечивает ряд возможностей по оптимизации работы вашего проекта. Одна из таких особенностей – это ленивая загрузка модулей, что позволяет подгружать различные модули с определенным функционалом по мере необходимости, а не сразу при старте приложения. Это позволяет сократить размер изначально загружаемого кода, уменьшить нагрузку на клиенте и т.д. Об этой возможности Ангуляр можно найти довольно много материалов и ознакомиться с ними подробнее.  Однако мы можем пойти дальше, и загружать лениво не только целые модули, но и отдельные компоненты на странице. Давайте посмотрим, как это можно сделать, используя уже изученные методы из первой части статьи. Создадим компонент BarComponent Тут присутствует свойство title, а также свойство titleChanges, на которое можно подписаться и принимать исходящие из компонента события. Теперь давайте посмотрим, как лениво загрузить этот компонент, динамически его создать, и получить доступ к его свойствам. Сперва, как и в первой части статьи, получим ссылку на контейнер через ViewChild. После этого нужно загрузить сам компонент BarComponent. Синтаксис этой загрузки очень похож на синтаксис, используемый при ленивой загрузке модулей. Затем инжеткируем сервис ComponentFactoryResolver, чтобы пользоваться его методами для создания компонента. Дальнейшая последовательность действий аналогична динамическому созданию компонента. После выполнения всех действий, у нас есть доступ к компоненту и его свойствам. Тут нужно обратить внимание, что мы не используем декораторы Input и Output, потому что мы общаемся с компонентом не через шаблон, а напрямую взаимодействуем с экземпляром компонента прямо в коде.  Однако если посмотреть на созданный компонент, можно сделать вывод что он довольно бесполезный и пригодится только чтобы отображать данные из входных свойств. Для полноты картины, было бы здорово обеспечить возможность использования остальные возможности Ангуляра в нем, например: другие компоненты, директивы, пайпы. Для решения этой проблемы мы создадим BarModule, и добавим туда все необходимое. (В последней версии Ангуляр, а на данный момент — это 16 версия, появилась возможность использовать standalone компоненты и напрямую подключать в него все используемые компоненты, модули, директивы и т.д.) Самое интересное, что благодаря механизму tree-shaking, если единственное место, где мы будем использовать модуль ReactiveFormsModule — это наш компонент BarComponent, то исходный код реактивных форм загрузится только при загрузке BarComponent. Это открывает новые возможности в вопросах оптимизации приложения. Вышеописанный синтаксис отлично подойдет для использования в проектах, где версия Ангуляр 12 и ниже. Однако начиная с 13 версии класс ComponentFactoryResolver был отмечен как deprecated, и это повлияло на процесс создания динамических компонентов, так как теперь из последовательности действий ушел один шаг, а именно создание фабрики компонента.  Теперь же для создания компонента можно напрямую обращаться к методу createComponent и передавать класс создаваемого компонента в качестве параметра, на выходе получится тот же результат. Динамическое создание компонентов открывает большие возможности по взаимодействию с ними и их управлению. Помимо всего этого в шаблонах компонента остается гораздо меньше кода с описанием всех input и output свойств, что так же хорошо влияет на весь проект. Ну и самое главное, это вопросы оптимизации. Благодаря более тонкой работе с компонентами, их динамическому созданию и ленивой загрузке открываются всё большие возможности по оптимизации приложения и улучшению пользовательского опыта при работе с ним. Данная статья не раскрывает собой все вопросы по данной теме, поэтому я советую вам более подробно ознакомиться со всеми материалами, которые существуют по тематике динамических компонентов.  Динамическое создание компонентов мощный инструмент, способный дать вашему проекту новые преимущества. В свою очередь вы как разработчик, изучив досконально этот вопрос, добавите себе в копилку ценные и важные навыки. Буду рад обратной связи в карму или в комментариях.