Модальные диалоги отлично подходят, когда вам нужно ограничить пользователя определенным действием, прежде чем он сможет вернуться к нормальному использованию приложения. Например, когда вы пытаетесь закрыть Microsoft Word без сохранения, отображается диалоговое окно, в котором вы выбираете возобновление работы (опция «Отмена») или закрытие программы (сохраняя или не сохраняя вашу работу). Появляется модальное диалоговое окно, потому что вы не можете продолжать использовать Word, пока не выберете один из доступных вариантов. А пока вы можете только смотреть на диалог.

Но давайте посмотрим на другой пример: операцию выхода. Допустим, пользователь нажимает кнопку выхода в вашем приложении, но вместо того, чтобы сразу же выйти из системы, вы хотите подтвердить, что именно это пытается сделать пользователь. В конце концов, они могли нажать кнопку по ошибке. Кстати, именно это я покажу вам сегодня, как создать компонент модального диалога выхода в Angular (8). Как только пользователь нажимает кнопку выхода, появляется модальное окно с двумя вариантами для пользователя: «Выход», которое подтверждает намерение пользователя, и «Вернуться», которое закрывает модальное окно и возвращает пользователя к нормальному использованию заявление.

Прежде чем мы перейдем к коду, я хочу предисловить его, пояснив, что эта статья написана в предположении, что вы уже знакомы с Angular. Само получившееся приложение очень простое, поэтому, если у вас есть базовое представление о структуре, все будет в порядке. Для использования модального окна нам понадобятся только две вещи: создать кнопку в корневом компоненте (app-root) и создать новый компонент, который будет самим модальным окном.

Настройка проекта

Сначала нам нужно создать новый проект Angular через командную строку:

ng new modal-component
cd modal-component
code .

Первая команда создает новый проект под названием modal-component. При запросе маршрутизации вы можете выбрать то, что вам больше нравится, поскольку это не влияет на этот пример. В качестве формата таблицы стилей выберите CSS. Вторая команда перемещает нас внутрь папки, созданной для проекта. Третья команда, code ., представляет собой удобный ярлык для открытия кода Visual Studio в текущем рабочем каталоге, то есть в папке проекта. Это просто удобный ярлык, если вы используете Visual Studio Code в качестве редактора.

Теперь, когда наш проект открыт в редакторе кода, нам нужно установить в проект одну вещь: Angular Material. Если вы не знакомы, он включает в себя набор готовых компонентов, готовых к добавлению в проект. В этом примере мы будем использовать его MatButton для, как вы уже догадались, кнопок и MatDialog для создания модального диалога.

Итак, чтобы установить библиотеку, вернитесь в командную строку и введите

ng add @angular/material

При установке материала вам будет предложено три вопроса: тема, настройка HammerJS и настройка анимации материала. Вы можете выбрать любую тему, которую предпочитаете, поскольку она не влияет на нашу функциональность, но, пожалуйста, выберите настройку анимации материала, иначе это приведет к поломке приложения. Для HammerJS не настраивайте его. Если у вас есть какие-либо сомнения относительно установки Angular Material, обратитесь к официальной Начальной странице.

Теперь, когда Angular Material настроен, нам просто нужно сделать еще одну вещь, которая не является фактическим кодом: создать модальный компонент. Я имею в виду, конечно, не готовую версию, а компонент, который будет модальным. Для этого введите

ng generate component modal

в командной строке. Таким образом, эта команда создает в приложении новый компонент с именем modal (или, скорее, app-modal). Теперь мы наконец можем приступить к написанию кода!

Первое, что мы сделаем, - это добавим новый ключ @NgModule в файлapp.module.ts, а также выполним некоторые операции импорта, как показано в следующем тексте кода:

Согласно документации, это цель entryComponents: «Набор компонентов для компиляции, когда этот NgModule определен, чтобы их можно было динамически загружать в представление». На практике, если бы это не было установлено, MatDialog не загружался бы должным образом (в нашем случае MatDialog будет использовать ModalComponent, компонент, который мы создали ранее). Для импорта нам нужно импортировать модули Angular Material, которые мы будем использовать.

Глобальные стили

Теперь, когда все настройки закончились, мы можем, наконец, сосредоточиться на написании HTML, CSS и TypeScript. Да и кстати, вы можете запустить проект, введя

ng serve --open

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

Прежде чем касаться любого компонента, давайте сразу же установим глобальные стили в файле styles.css:

Пока сосредоточимся только на изменениях в элементах html и body, позже мы вернемся к mat-dialog-container#modal-component набору правил.

компонент корневого приложения

Определив глобальные стили, мы можем перейти к отдельным компонентам. Начнем с компонента app-root, «домашней страницы» приложения, который будет выглядеть следующим образом:

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

Итак, начнем с HTML:

Как видите, все просто. Элемент main содержит весь компонент, который содержит только один другой элемент: кнопку выхода. Но обратите внимание на атрибут mat-raised-button. Это то, что превращает обычную кнопку HTML в кнопку Angular Material, включая связанные с ней стили и анимацию. Хотя мы также даем ему id, чтобы немного изменить его стили:

Также довольно просто, изменились только цвет текста, цвет фона и границы кнопки. Больше ничего о CSS для app-root. Осталось еще кое-что изменить для этого компонента: его TypeScript. Наша цель - создать функцию, которая вызывается при нажатии кнопки выхода. А что на самом деле делает эта функция? Откройте модальный компонент, то есть MatDialog:

Хорошо, теперь позвольте мне объяснить, что происходит в этом файле. Сначала обратите внимание на три новых импорта: MatDialog и MatDialogConfig (оба из Angular Material) и ModalComponent, класс компонента, который мы создали. В конструктор класса app-root мы вводим зависимость: MatDialog, о которой мы говорили с самого начала. Если бы мы не внедрили его, мы не сможем открыть диалоговое окно.

Затем мы делаем две вещи внутри функции openModal(): настраиваем открытие диалогового окна с помощью объекта MatDialogConfig и фактически открываем модальное окно. Мы используем четыре варианта конфигурации:

  • disableClose: если пользователь щелкает за пределами модального окна, оно не закрывается;
  • id: идентификатор, для которого диалоговое окно будет называться (полезно для CSS);
  • height: высота диалога;
  • width: ширина диалога.

В последней строке функции мы открываем модальный диалог, вызывая метод open() объекта MatDialog, введенного в конструктор. Чтобы открыть диалоговое окно, нам нужно указать, какой компонент будет отображаться внутри вместе с соответствующим объектом конфигурации.

И это все, что касается компонента app-root, теперь, когда вы нажимаете кнопку выхода, он открывает пустой модальный диалог!

модальный компонент приложения

Теперь нам нужно взглянуть на app-modal компонент, который мы создали. Опять же, нам нужно изменить его HTML, CSS и TypeScript, но сначала позвольте мне показать вам, как модальное окно будет выглядеть в итоге:

Опять же, мы начинаем с HTML:

У нас есть единственный элемент div, который обертывает все содержимое модального окна, а затем это содержимое разделяется на три части:

  1. Заголовок («заголовок», показанный в модальном окне);
  2. Краткое описание действия, которое пытается выполнить пользователь (в данном случае я написал шутку, чтобы не дать им выйти из системы);
  3. Нижний колонтитул, который состоит из двух кнопок: одна для подтверждения действия («Выход») и вторая для отмены действия («Вернуться»).

Также довольно простые вещи, и обратите внимание, как мы снова использовали MatButtons для модального окна.

Теперь у CSS есть трюк из-за материала Angular.

То, что показано выше, является довольно простым CSS. В первом наборе правил (#modal-content-wrapper) мы преобразовываем диалог в трехстрочную сетку, по одной строке для каждой из перечисленных частей. Остальные наборы правил используются только для позиционирования и незначительных корректировок стиля (примечание: если вы не знакомы с макетом сетки CSS, я написал вводную статью здесь на случай, если вам интересно).

Что сложно в CSS модального окна, так это стилизация компонента Angular MaterialMatDialog. Если вы посмотрите на таблицу стилей выше, там нет набора правил для дизайна самого диалога. modal-content-wrapper - это идентификатор HTML-элемента, который обертывает все содержимое внутри модального, а не фактического модального окна.

Введите объект конфигурации MatDialog. Помните, когда мы писали конфигурации для открытия диалогового окна в app-root? Мы передали ему собственный идентификатор modal-component, который теперь можно использовать для стилизации диалогового окна. Но мы не можем сделать это в CSS app-modal, поскольку это фактически содержание диалога, а не сам диалог. Следовательно, тот набор правил, который я просил игнорировать еще в styles.css. Хотя этот файл содержит глобальные наборы правил CSS, у нас нет другого выбора, кроме как установить здесь стили для этого конкретного MatDialog.

В отличие от кнопок, которые «преобразуются» в MatButtons путем добавления атрибута mat-raised-button, который по-прежнему позволяет нам изменять стили кнопок в CSS компонентов, в которых они используются, диалоговое окно работает иначе, поскольку оно почти находится в подвешенном состоянии между app-root ( где он открыт) и app-modal (компонент, который он содержит). Короче говоря, мы стилизуем MatDialog в глобальном файле styles.css, потому что мы не можем получить к нему доступ ни в одной из таблиц стилей других компонентов.

Но поскольку мы имеем дело с глобальными стилями, нам нужно быть осторожными со спецификой нашего набора правил, чтобы он не повлиял на другие диалоги, которые могут быть в приложении. Итак, давайте еще раз посмотрим на суть styles.css кода.

Посмотрите на последний набор правил, который отвечает за стили нашего MatDialog. Мы используем CSS-селектор имени тега (mat-dialog-container), который перехватывает любые MatDialog в приложении, а затем ограничивает его только теми, у которых есть идентификатор modal-component, другими словами, мы выбираем только модальный режим выхода из системы, с которым мы работаем. Компоненты Angular Material могут быть сложными в стилизации, поэтому существует очевидный компромисс между их удобством использования и потребностями каждого проекта.

Если убрать CSS, осталось изменить только одно - это TypeScript app-modal. Здесь нам нужно сделать три вещи:

  • Вставьте объект MatDialogRef в компонент, чтобы получить доступ к методам диалогового окна (а именно, закрыть диалоговое окно);
  • Создайте функцию actionFunction() для кнопки «Выход»;
  • Создайте функцию closeModal() для кнопки «Назад».

Какую бы кнопку ни нажимал пользователь, для демонстрации он будет возвращен на «домашнюю страницу» приложения. Другими словами, какую бы кнопку ни нажимал пользователь, модальное окно закроется и снова покажет большую кнопку «Выход».

Итак, в чем разница между кнопкой «Выход» (той, что находится внутри модального окна) и кнопкой «Вернуться»? Первый отображает окно предупреждения перед закрытием модального окна, чтобы пользователь знал, что он вышел из системы. Вторая кнопка просто закрывает модальное окно.

Теперь давайте на минутку отойдем от демонстрации. Как только пользователь нажимает кнопку «Выход», и приложение вызывает функцию actionFunction(), здесь вступает ваша логика для выполнения желаемого действия. В случае реального выхода из системы у вас будет код для завершения работы пользователя. сеанс. Другая функция, функция, которая отменяет операцию, инициированную пользователем, просто закрывает диалоговое окно и позволяет ему вернуться к нормальному использованию приложения.

Заключение

И на этом мы подошли к концу объяснения. Если вы следовали за кодом, теперь у вас есть рабочий компонент модального диалога, который было очень просто реализовать. Конечно, в вашем реальном приложении вы будете включать службы для взаимодействия с сервером, и модальное окно может применяться везде, где вам нужно, чтобы пользователь подтвердил свое действие перед его фактическим выполнением, например, при удалении элемента.

Если у вас запущен проект, откройте браузер по адресу localhost: 4200, чтобы увидеть его завершенное состояние. Если он не запущен, введите ng serve --open в командной строке, и он автоматически откроет новую вкладку в вашем браузере.

В завершение статьи я оставляю ссылку на полный код в репозитории GitHub.

Любые конструктивные отзывы приветствуются, поскольку это самая длинная техническая статья, которую я написал, и, вероятно, есть много способов, которыми я могу улучшить. Хорошего дня :)