Как управлять модальными окнами в приложениях Angular
27 февраля 2024 г.Каждое приложение состоит из компонентов одного и того же типа — кнопок, полей ввода, раскрывающихся списков и т. д., и в этом списке есть модальные окна. Причина проста — модальные окна позволяют нам общаться с пользователем и не перегружать пользовательский интерфейс дополнительной информацией, пока она не станет необходимой. В этой статье я рассмотрю один из подходов к управлению модальными окнами в приложениях Angular.
:::информация В примерах статьи мы используем библиотеку primeng для модальных окон. Ваш случай может быть другим. Общая идея будет одинаковой, несмотря на библиотеки, но API может быть разным; имейте это в виду.
:::
Модальные окна — это обычные компоненты — у них есть разметка, стиль и селектор. Но в отличие от обычных компонентов их обычно не обязательно показывать на странице сразу. Они нужны нам только для результата действий пользователей — подтверждения, отмены, заполнения формы и т. д. Поэтому мы не будем включать их в нашу сборку — мы будем загружать их динамически, только если они нам потребуются. Давайте посмотрим пример:
public openModal(): void {
const modalComponent = async (): Promise<any> => import('./path-to-your-modal');
this.modalService.open(modalComponent());
}
Здесь у нас есть подход динамического импорта. Это означает, что наш компонент будет загружен, когда мы вызовем метод openModal
. Это весьма полезно, поскольку мы не загружаем модальное окно в наш чанк сразу — только тогда, когда оно нужно пользователю. Этот подход может помочь вам немного уменьшить размер пакета, особенно если ваши модальные окна полны логики и компонентов.
В целом это рабочее решение. Но мы можем пойти дальше. Давайте создадим сервис, который будет обрабатывать динамический импорт и возвращать экземпляр модального окна:
import { Injectable } from '@angular/core';
import { DialogService } from 'primeng/dynamicdialog';
@Injectable({ providedIn: 'root' })
export class CustomModalService {
public modalWindowComponents: { [key: string]: () => Promise<any> } = {
ConfirmModalComponent: () =>
import('your-path/to-component').then((component) => component.ConfirmModalComponent),
};
constructor(private modalService: DialogService) {}
public async openDynamicDialogModal({
componentName,
data,
}: {
componentName: string;
data?: { [key: string]: any };
}): Promise<any> {
const modalComponent = this.modalService.open(await this.modalWindowComponents[componentName](), { ...data });
modalComponent.onClose.subscribe(() => {
// some logic
});
return modalComponent;
}
}
Здесь мы видим несколько важных вещей:
- Мы используем объект для хранения импорта модальных окон, где ключом является имя компонента, а значением — функция импорта, которая возвращает Promise;
- Наш метод берет объект params с именем компонента (чтобы получить функцию импорта из объекта) и некоторые дополнительные данные, которые содержат все, что вы хотите для компонента или его конфигурации. Также у нас есть подписка на близкие мероприятия. Закрытие окон удобнее обрабатывать в одном месте;
- Мы возвращаем Promise с импортированным компонентом. Это позволяет нам обрабатывать логику для каждого модального окна. ол>
Вот пример использования этого сервиса:
public async handleOpeningModalWindow(): Promise<void> {
const dialogRef = await this.primengModalService.openDynamicDialogModal({
componentName: 'DeleteStreamModalComponent',
data: {
// your params
},
});
dialogRef.onClose
.pipe(
// your pipes
)
.subscribe(() => {
// your logic
});
}
Заключение
Приняв описанный выше подход, разработчики Angular могут создать более компактную и управляемую систему модальных окон. Эта стратегия не только уменьшает размер пакета, но также предлагает унифицированный метод модального управления и настройки. Использование динамического импорта и архитектуры на основе сервисов позволяет разработчикам оптимизировать взаимодействие с пользователем, сохраняя при этом масштабируемость и эффективность кода.
Оригинал