Usando a API DModal para renderizar janelas modais (aka popups/dialogos) no Discourse

O Discourse 3.1.0.beta6 vem com uma nova API baseada em componentes <DModal>.

:information_source: Isso substitui a antiga API baseada em controladores, que agora está obsoleta. Se você possui modais existentes usando as APIs antigas, consulte o guia de migração aqui.

Renderizando um Modal

Modais são renderizados incluindo o componente <DModal> em um template Handlebars. Se você ainda não tem um template adequado, consulte Using Plugin Outlet Connectors from a Theme or Plugin.

Um modal simples seria algo assim:

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

{{#if this.modalIsVisible}}
  <DModal @title="Meu Modal" @closeModal={{fn (mut this.modalIsVisible) false}}>
    Olá mundo, este é algum conteúdo em um modal
  </DModal>
{{/if}}

:information_source: O helper mut é usado aqui como uma maneira exclusiva de hbs para definir um valor. Você também pode definir modalIsVisible usando qualquer outro método padrão do Ember.

Este exemplo criará um modal simples como este:

Envolver em um componente

Antes de introduzir qualquer complexidade adicional, geralmente é melhor encapsular seu novo Modal em sua própria definição de Componente. Vamos mover o conteúdo do <DModal> para dentro de um novo componente <MyModal />.

// components/my-modal.gjs
<template>
  <DModal @title="Meu Modal" @closeModal={{@closeModal}}>
    Olá mundo, este é algum conteúdo em um modal
  </DModal>
</template>

Atualizar este arquivo .gjs para um componente baseado em classe permitirá que você introduza lógica e estado mais complexos.

Para utilizar o novo componente, atualize o local de chamada para referenciá-lo, certificando-se de passar um argumento @closeModal.

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

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

Adicionando um rodapé

Muitos modais possuem algum tipo de chamada para ação. No Discourse, eles tendem a estar localizados na parte inferior do modal. Para tornar isso possível, o DModal possui vários ‘blocos nomeados’ que podem ter conteúdo renderizado dentro deles. Aqui está o exemplo atualizado para incluir dois botões no rodapé, sendo um deles nosso botão padrão DModalCancel.

<DModal @title="Meu Modal" @closeModal={{@closeModal}}>
  <:body>
    Olá mundo, este é algum conteúdo em um modal
  </:body>
  <:footer>
    <DButton class="btn-primary" @translatedLabel="Enviar" />
    <DModalCancel @close={{@closeModal}} />
  </:footer>
</DModal>

Renderizando um modal a partir de um contexto não-hbs

Idealmente, as instâncias de <DModal> devem ser renderizadas dentro de um template Ember usando a técnica declarativa demonstrada acima. Se isso não for viável para seu caso de uso, pode ser feito injetando o serviço modal e chamando modal.show().

Certifique-se de ter encapsulado seu modal em seu próprio componente conforme descrito acima. Em seguida, acione o modal passando uma referência da sua classe de componente para showModal:

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

// (injetar o serviço modal no local relevante)

// Adicione esta chamada sempre que quiser abrir o modal.
// Um argumento `@closeModal` será passado automaticamente para seu componente.
this.modal.show(MyModal);

// Opcionalmente, passe um parâmetro `model`. Passado como `@model` para seu componente.
// Isso pode incluir dados, bem como ações/callbacks para seu Modal usar.
this.modal.show(MyModal, {
  model: { topic: this.topic, someAction: this.someAction },
});

// `modal.show()` retorna uma promessa, então você pode esperar que ela seja fechada
// Ela será resolvida com os dados passados para a ação `@closeModal`
const result = await this.modal.show(MyModal);

Mais personalização!

O <DModal> possui vários blocos nomeados e argumentos. Consulte o guia de estilo interativo para argumentos e a implementação do template d-modal para blocos nomeados.


Este documento está sob controle de versão - sugira alterações no GitHub.

17 curtidas

Uma postagem foi dividida em um novo tópico: Posso exibir um modal do head_tag