Usando a API DModal para renderizar janelas Modais (também conhecidas como popups/diálogos) no Discourse

\nO Discourse 3.1.0.beta6 é lançado com uma API baseada no novo componente <DModal>.

:information_source: Isso substitui a antiga API baseada em controller, que agora está obsoleta. Se você tem modais existentes usando as APIs antigas, confira 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, confira Using Plugin Outlet Connectors from a Theme or Plugin.

Um modal simples ficaria algo assim:

<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: 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 Ember padrão.

Este exemplo criará um Modal simples como este:

Envolvendo em um componente

Antes de introduzir mais complexidade, geralmente é melhor envolver seu novo Modal em sua própria definição de Componente. Vamos mover as coisas do <DModal> para dentro de um novo componente <MyModal />

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

A introdução de um arquivo de componente .js complementar permitirá que você introduza lógica e estado mais complexos.

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

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

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

Adicionando um rodapé

Muitos modais têm algum tipo de chamada para ação. No Discourse, estas tendem a ser localizadas na parte inferior do modal. Para tornar isso possível, o DModal tem uma série de ‘blocos nomeados’ nos quais o conteúdo pode ser renderizado. Aqui está o exemplo atualizado para incluir dois botões no rodapé, um dos quais é nosso botão padrão 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>

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

Idealmente, as instâncias de <DModal> devem ser renderizadas a partir de um template Ember handlebars usando a técnica declarativa demonstrada acima. Se isso não for viável para o seu caso de uso (por exemplo, você precisa acionar um modal a partir dos sistemas de renderização ‘raw-hbs’ ou ‘widget’ legados do Discourse), isso pode ser feito injetando o serviço modal e chamando modal.show().

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

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

// (injete 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 e também ações/callbacks para seu Modal usar.
this.modal.show(MyModal, {
  model: { topic: this.topic, someAction: this.someAction },
});

// `modal.show()` retorna uma promise, 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 customização!

<DModal> tem uma série de blocos nomeados e argumentos. Consulte o styleguide interativo para argumentos, e a implementação do template d-modal para blocos nomeados.


Este documento é controlado por 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