Utilisation de l'API DModal pour rendre des fenêtres Modal (également appelées popups/dialogues) dans Discourse

Discourse 3.1.0.beta6 est livré avec une toute nouvelle API basée sur le composant \u003cDModal\u003e.

:information_source: Ceci remplace l’ancienne API basée sur les contrôleurs, qui est maintenant obsolète. Si vous avez des modales existantes utilisant les anciennes API, consultez le guide de migration ici.

Rendu d’une modale

Les modales sont rendues en incluant le composant \u003cDModal\u003e dans un template handlebars. Si vous n’avez pas encore de template approprié, consultez Using Plugin Outlet Connectors from a Theme or Plugin.

Une modale simple ressemblerait à ceci :

\u003cDButton
  @translatedLabel="Afficher la modale"
  @action={{fn (mut this.modalIsVisible) true}}
/\u003e

{{#if this.modalIsVisible}}
  \u003cDModal @title="Ma Modale" @closeModal={{fn (mut this.modalIsVisible) false}} \u003e
    Bonjour le monde, voici du contenu dans une modale
  \u003c/DModal\u003e
{{/if}}

:information_source: L’ helper mut est utilisé ici comme moyen de définir une valeur uniquement en hbs. Vous pourriez également définir modalIsVisible en utilisant toute autre méthode Ember standard.

Cet exemple créera une modale simple comme celle-ci :

Encapsulation dans un composant

Avant d’introduire plus de complexité, il est généralement préférable d’encapsuler votre nouvelle modale dans sa propre définition de composant. Déplaçons les éléments \u003cDModal\u003e dans un nouveau composant \u003cMyModal /\u003e.

{{! components/my-modal.hbs }}
\u003cDModal @title="Ma Modale" @closeModal={{@closeModal}}\u003e
  Bonjour le monde, voici du contenu dans une modale
\u003c/DModal\u003e

L’introduction d’un fichier de composant .js compagnon vous permettra d’introduire une logique et un état plus complexes.

Pour utiliser le nouveau composant, mettez à jour l’appel pour y faire référence, en vous assurant de passer un argument @closeModal.

\u003cDButton
  @translatedLabel="Afficher la modale"
  @action={{fn (mut this.modalIsVisible) true}}
/\u003e

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

Ajout d’un pied de page

De nombreuses modales ont une sorte d’appel à l’action. Dans Discourse, ceux-ci ont tendance à être situés en bas de la modale. Pour rendre cela possible, DModal a un certain nombre de ‘blocs nommés’ dans lesquels du contenu peut être rendu. Voici l’exemple mis à jour pour inclure deux boutons dans le pied de page, dont l’un est notre bouton standard DModalCancel.

\u003cDModal @title="Ma Modale" @closeModal={{@closeModal}}\u003e
  \u003c:body\u003e
    Bonjour le monde, voici du contenu dans une modale
  \u003c/:body\u003e
  \u003c:footer\u003e
    \u003cDButton class="btn-primary" @translatedLabel="Soumettre" /\u003e
    \u003cDModalCancel @close={{@closeModal}} /\u003e
  \u003c/:footer\u003e
\u003c/DModal\u003e

Rendu d’une modale depuis un contexte non-hbs

Idéalement, les instances de \u003cDModal\u003e devraient être rendues à partir d’un template handlebars Ember en utilisant la technique déclarative démontrée ci-dessus. Si cela n’est pas réalisable pour votre cas d’utilisation (par exemple, si vous devez déclencher une modale à partir des anciens systèmes de rendu ‘raw-hbs’ ou ‘widget’ de Discourse), cela peut être fait en injectant le service modal et en appelant modal.show().

Assurez-vous d’avoir encapsulé votre modale dans son propre composant comme décrit ci-dessus. Ensuite, déclenchez la modale en passant une référence de votre classe de composant à showModal:

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

// (injectez le service modal à l'endroit approprié)

// Ajoutez cet appel chaque fois que vous souhaitez ouvrir la modale.
// Un argument `@closeModal` sera automatiquement passé à votre composant.
this.modal.show(MyModal);

// Facultativement, passez un paramètre '`model`'. Passé comme `@model` à votre composant.
// Cela peut inclure des données, ainsi que des actions/callbacks pour que votre modale les utilise.
this.modal.show(MyModal, {
  model: { topic: this.topic, someAction: this.someAction },
});

// `modal.show()` renvoie une promesse, vous pouvez donc attendre sa fermeture
// Elle sera résolue avec les données passées à l'action `@closeModal`
const result = await this.modal.show(MyModal);

Plus de personnalisation !

\u003cDModal\u003e a un certain nombre de blocs nommés et d’arguments. Consultez le guide de style interactif pour les arguments, et l’implémentation du template d-modal pour les blocs nommés.


\u003csmall\u003eCe document est contrôlé par version - suggérez des changements sur 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 « J'aime »

Une publication a été divisée en un nouveau sujet : Puis-je afficher une modale depuis head_tag