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

Discourse 3.1.0.beta6 には、全く新しいコンポーネントベースの DModal API が搭載されています。

:information_source: これは、非推奨となった古いコントローラーベースの API を置き換えるものです。既存の古い API を使用しているモーダルについては、移行ガイドをこちらで確認してください。

モーダルを描画する

モーダルは、handlebars テンプレートに DModal コンポーネントを含めることで描画されます。適切なテンプレートがまだない場合は、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}}>
  Hello world, this is some content in a modal
</DModal>

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

新しいコンポーネントを使用するには、コールサイトを更新してそれを参照し、@closeModal 引数を渡すようにします。

<DButton
  @translatedLabel="モーダルを表示"
  @action={{fn (mut this.modalIsVisible) true}}
/>

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

フッターの追加

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

<DModal @title="マイモーダル" @closeModal={{@closeModal}}>
  <:body>
    Hello world, this is some content in a modal
  </:body>
  <:footer>
    <DButton class="btn-primary" @translatedLabel="送信" />
    <DModalCancel @close={{@closeModal}} />
  </:footer>
</DModal>

non-hbs コンテキストからモーダルを描画する

理想的には、DModal インスタンスは、上記で説明した宣言的な方法を使用して Ember handlebars テンプレート内から描画されるべきです。もしそれがユースケースで実現不可能である場合(例:Discourse のレガシーな「raw-hbs」や「ウィジェット」レンダリングシステムからモーダルをトリガーする必要がある場合)、modal サービスをインジェクションし、modal.show() を呼び出すことで実現できます。

上記で説明したように、モーダルを独自のコンポーネントでラップしていることを確認してください。次に、コンポーネントクラスへの参照を showModal に渡すことで、モーダルをトリガーします。

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

// (関連する場所に modal サービスをインジェクションしてください)

// モーダルを開きたいときはいつでもこの呼び出しを追加します。
// @closeModal 引数がコンポーネントに自動的に渡されます。
this.modal.show(MyModal);

// オプションで、'model' パラメータを渡すこともできます。これはコンポーネントに @model として渡されます。
// これには、データや、Modal が使用するためのアクション/コールバックを含めることができます。
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

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