Как управлять модальными окнами в приложениях Angular

Как управлять модальными окнами в приложениях 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;
    }
}

Здесь мы видим несколько важных вещей:

  1. Мы используем объект для хранения импорта модальных окон, где ключом является имя компонента, а значением — функция импорта, которая возвращает Promise;
  2. Наш метод берет объект params с именем компонента (чтобы получить функцию импорта из объекта) и некоторые дополнительные данные, которые содержат все, что вы хотите для компонента или его конфигурации. Также у нас есть подписка на близкие мероприятия. Закрытие окон удобнее обрабатывать в одном месте;
  3. Мы возвращаем Promise с импортированным компонентом. Это позволяет нам обрабатывать логику для каждого модального окна.
  4. Вот пример использования этого сервиса:

    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 могут создать более компактную и управляемую систему модальных окон. Эта стратегия не только уменьшает размер пакета, но также предлагает унифицированный метод модального управления и настройки. Использование динамического импорта и архитектуры на основе сервисов позволяет разработчикам оптимизировать взаимодействие с пользователем, сохраняя при этом масштабируемость и эффективность кода.


    Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE