Использование API DModal для отображения модальных окон (также известных как всплывающие окна/диалоги) в Discourse

Discourse 3.1.0.beta6 включает в себя совершенно новый API на основе компонента <DModal>.

:information_source: Этот API заменяет старый API на основе контроллеров, который теперь устарел. Если у вас есть существующие модальные окна, использующие старые API, ознакомьтесь с руководством по миграции здесь.

Отрисовка модального окна

Модальные окна отрисовываются путем включения компонента <DModal> в шаблон Handlebars. Если у вас еще нет подходящего шаблона, ознакомьтесь с материалом по ссылке Using Plugin Outlet Connectors from a Theme or Plugin.

Простое модальное окно будет выглядеть примерно так:

<DButton
  @translatedLabel="Показать модальное окно"
  @action={{fn (mut this.modalIsVisible) true}}
/>

{{#if this.modalIsVisible}}
  <DModal @title="Мое модальное окно" @closeModal={{fn (mut this.modalIsVisible) false}}>
    Привет, мир, это контент внутри модального окна
  </DModal>
{{/if}}

:information_source: Здесь используется помощник mut как способ установки значения, специфичный для hbs. Вы также можете установить modalIsVisible с помощью любого другого стандартного метода Ember.

Этот пример создаст простое модальное окно, похожее на это:

Инкапсуляция в компонент

Прежде чем добавлять какую-либо сложность, обычно лучше обернуть новое модальное окно в собственное определение компонента. Перенесем содержимое <DModal> внутрь нового компонента <MyModal />.

{{! components/my-modal.hbs }}
<DModal @title="Мое модальное окно" @closeModal={{@closeModal}}>
  Привет, мир, это контент внутри модального окна
</DModal>

Добавление сопутствующего файла компонента .js позволит реализовать более сложную логику и управление состоянием.

Чтобы использовать новый компонент, обновите место вызова, чтобы он ссылался на него, и обязательно передайте аргумент @closeModal.

<DButton
  @translatedLabel="Показать модальное окно"
  @action={{fn (mut this.modalIsVisible) true}}
/>

{{#if this.modalIsVisible}}
  <MyModal @closeModal={{fn (mut this.modalIsVisible) false}} />
{{/if}}

Добавление подвала

Во многих модальных окнах есть призыв к действию. В Discourse они обычно располагаются в нижней части модального окна. Чтобы это стало возможным, у DModal есть несколько «именованных блоков», в которые можно отрисовывать контент. Вот обновленный пример с двумя кнопками в подвале, одна из которых — наша стандартная кнопка DModalCancel:

<DModal @title="Мое модальное окно" @closeModal={{@closeModal}}>
  :body
    Привет, мир, это контент внутри модального окна
  /:body
  :footer
    <DButton class="btn-primary" @translatedLabel="Отправить" />
    <DModalCancel @close={{@closeModal}} />
  /:footer
</DModal>

Отрисовка модального окна из контекста, отличного от hbs

В идеале экземпляры <DModal> должны отрисовываться из шаблона Ember Handlebars с использованием декларативного метода, показанного выше. Если это невозможно для вашего случая использования (например, вам нужно вызвать модальное окно из устаревших систем отрисовки Discourse «raw-hbs» или «widget»), это можно сделать, внедрив сервис modal и вызвав modal.show().

Убедитесь, что вы инкапсулировали ваше модальное окно в собственный компонент, как описано выше. Затем вызовите модальное окно, передав ссылку на класс вашего компонента в showModal:

import MyModal from "discourse/components/my-modal";

// (внедрите сервис modal в соответствующем месте)

// Добавьте этот вызов всякий раз, когда нужно открыть модальное окно.
// Аргумент `@closeModal` будет автоматически передан вашему компоненту.
this.modal.show(MyModal);

// Опционально передайте параметр `model`. Он будет передан вашему компоненту как `@model`.
// Это может включать данные, а также действия/коллбэки для использования модальным окном.
this.modal.show(MyModal, {
  model: { topic: this.topic, someAction: this.someAction },
});

// `modal.show()` возвращает промис, поэтому можно дождаться его закрытия.
// Он будет разрешен с данными, переданными в действие `@closeModal`.
const result = await this.modal.show(MyModal);

Еще больше возможностей настройки!

У <DModal> есть несколько именованных блоков и аргументов. Ознакомьтесь с интерактивным гайдлайном по аргументам и с реализацией шаблона d-modal по именованным блокам.


Этот документ находится под версионным контролем — предлагайте изменения на GitHub.

17 лайков

A post was split to a new topic: Can I show a modal from head_tag