Discourseでモーダルウィンドウ(ポップアップ/ダイアログ)をレンダリングするためのDModal APIの使用

Discourse 3.1.0.beta6 は、まったく新しい DModal コンポーネントベースの API を搭載しています。

:information_source: これは、現在非推奨となっている古いコントローラーベースの API に代わるものです。古い API を使用している既存のモーダルがある場合は、こちらの移行ガイドを参照してください。

モーダルのレンダリング

モーダルは、DModal コンポーネントを handlebars テンプレートに含めることでレンダリングされます。適切なテンプレートがまだない場合は、Using Plugin Outlet Connectors from a Theme or Plugin を参照してください。

簡単なモーダルは次のようになります。

<DButton
  @translatedLabel="Show Modal"
  @action={{fn (mut this.modalIsVisible) true}}
/>

{{#if this.modalIsVisible}}
  <DModal @title="My Modal" @closeModal={{fn (mut this.modalIsVisible) false}}>
    Hello world, this is some content in a modal
  </DModal>
{{/if}}

:information_source: ここで使用されている mut ヘルパー は、値を設定するための hbs のみでの方法です。他の標準的な Ember の方法で modalIsVisible を設定することもできます。

この例では、次のような簡単なモーダルが作成されます。

コンポーネントでのラップ

さらに複雑にする前に、新しいモーダルを独自のコンポーネント定義でラップするのが通常は最善です。DModal の部分を新しい MyModal コンポーネント内に移動しましょう。

{{! components/my-modal.hbs }}
<DModal @title="My Modal" @closeModal={{@closeModal}}>
  Hello world, this is some content in a modal
</DModal>

対応する .js コンポーネントファイルを紹介することで、より複雑なロジックと状態を導入できます。

新しいコンポーネントを使用するには、呼び出し元を更新して参照し、@closeModal 引数を渡すようにしてください。

<DButton
  @translatedLabel="Show Modal"
  @action={{fn (mut this.modalIsVisible) true}}
/>

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

フッターの追加

多くのモーダルには、何らかの呼び出しアクションがあります。Discourse では、これらは通常モーダルの下部に配置されます。これを可能にするために、DModal にはコンテンツをレンダリングできるいくつかの「名前付きブロック」があります。ここでは、フッターに 2 つのボタン(標準の DModalCancel ボタンを含む)を追加するように例を更新します。

<DModal @title="My Modal" @closeModal={{@closeModal}}>
  <:body>
    Hello world, this is some content in a modal
  </:body>
  <:footer>
    <DButton class="btn-primary" @translatedLabel="Submit" />
    <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()` は Promise を返すため、閉じられるのを待つことができます。
// `@closeModal` アクションに渡されたデータで解決されます。
const result = await this.modal.show(MyModal);

より多くのカスタマイズ性!

DModal には、多くの名前付きブロックと引数があります。引数についてはインタラクティブスタイルガイドを、名前付きブロックについてはd-modal テンプレート実装を参照してください。


このドキュメントはバージョン管理されています。変更はgithub で提案してください。

「いいね!」 17

投稿が新しいトピックに分割されました: head_tagからモーダルを表示できますか