使用 DModal API 在 Discourse 中渲染模态窗口(又称弹出窗口/对话框)

Discourse 3.1.0.beta6 附带了一个全新的基于组件的 \u003cDModal\u003e API。

:information_source: 这取代了旧的基于控制器的 API,后者现已弃用。如果您有使用旧 API 的现有模态框,请参阅此处的迁移指南。

渲染模态框

通过在 Handlebars 模板中包含 \u003cDModal\u003e 组件来渲染模态框。如果您还没有合适的模板,请查看 https://meta.discourse.org/t/using-plugin-outlet-connectors-from-a-theme-or-plugin/32727。

一个简单的模态框看起来像这样:

\u003cDButton
  @translatedLabel="显示模态框"
  @action={{fn (mut this.modalIsVisible) true}}
/\u003e

{{#if this.modalIsVisible}}
  \u003cDModal @title="我的模态框" @closeModal={{fn (mut this.modalIsVisible) false}}
    Hello world, this is some content in a modal
  \u003c/DModal
{{/if}}

:information_source: mut 助手 在这里用作仅限 hbs 的设置值的方法。您也可以使用任何其他标准的 Ember 方法来设置 modalIsVisible

此示例将创建一个简单的模态框,如下所示:

封装到组件中

在引入更多复杂性之前,通常最好将新的模态框封装到其自己的组件定义中。让我们将 \u003cDModal\u003e 部分移到一个新的 \u003cMyModal /\u003e 组件中

{{! components/my-modal.hbs }}
\u003cDModal @title="我的模态框" @closeModal={{@closeModal}}
  Hello world, this is some content in a modal
\u003c/DModal

引入一个配套的 .js 组件文件将允许您引入更复杂的逻辑和状态。

要使用新组件,请更新调用站点以引用它,确保传入 @closeModal 参数。

\u003cDButton
  @translatedLabel="显示模态框"
  @action={{fn (mut this.modalIsVisible) true}}
/\u003e

{{#if this.modalIsVisible}}
  \u003cMyModal @closeModal={{fn (mut this.modalIsVisible) false}} /\u003e
{{/if}}

添加页脚

许多模态框都有某种行动号召。在 Discourse 中,这些通常位于模态框的底部。为了实现这一点,DModal 有许多“命名块”,可以在其中渲染内容。这是更新后的示例,其中在页脚中包含两个按钮,其中一个是我们的标准 DModalCancel 按钮

\u003cDModal @title="我的模态框" @closeModal={{@closeModal}}
  \u003c:body\u003e
    Hello world, this is some content in a modal
  \u003c/:body
  \u003c:footer\u003e
    \u003cDButton class="btn-primary" @translatedLabel="提交" /\u003e
    \u003cDModalCancel @close={{@closeModal}} /\u003e
  \u003c/:footer
\u003c/DModal

从非 hbs 上下文中渲染模态框

理想情况下,\u003cDModal\u003e 实例应使用上述声明性技术从 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()` 返回一个 promise,因此您可以等到它关闭
// 它将使用传递给 `@closeModal` 操作的数据来解析
const result = await this.modal.show(MyModal);

更多可定制性!

\u003cDModal\u003e 有许多命名块和参数。有关参数,请查看交互式风格指南,有关命名块,请查看d-modal 模板实现


\u003csmall\u003e此文档是版本控制的 - 在 github 上建议更改。\u003c/small\u003e

\u003c!-- START DOCS ASSET MAP
[
{
“local_path”: “/assets/dmodal-api-1.png”,
“local_sha1”: “8dfd8ffa18409fdcac56e95e0f37e3b2c81af61e”,
“remote_short_url”: “upload://9eKVimqNmM9Q4apSPWsWrImfmQt.png”
},
{
“local_path”: “/assets/dmodal-api-2.png”,
“local_sha1”: “9e6b3ae3a40c9934fa89cea18d42a1138e9248d3”,
“remote_short_url”: “upload://yp2hfxwO9dNjAJtUnGU89azmz63.png”
}
]
END DOCS ASSET MAP –\u003e

17 个赞

帖子已拆分为新主题:Can I show a modal from head_tag