Usa Ember.PromiseProxyMixin in un tema

Recentemente è stato aggiunto Ember.PromiseProxyMixin ai moduli Ember nel nucleo di Discourse.

È un mixin Ember molto utile che ti consente di effettuare richieste asincrone e di lavorare facilmente con le Promise all’interno dei componenti Ember. Pensaci come React Suspense ma per Ember. Il potenziale è enorme per lo sviluppo di temi e plugin in Discourse.

Ecco la documentazione ufficiale di Ember per Ember.PromiseProxyMixin.

E qui puoi trovare un esempio dettagliato non specifico di Discourse su come utilizzare Ember.PromiseProxyMixin.

Fornirò un esempio semplice di come questo mixin può essere utilizzato all’interno di un tema Discourse. Diciamo che, per qualche motivo, nel componente topic-list-item desideri stilizzare l’avatar del poster se questi è un membro dello staff; in tal caso, l’avatar deve avere un bordo diverso.

Da qualche parte in topic-list-item.js(.es6) dovrai:

  • Importare EmberObject e PromiseProxyMixin ed estendere EmberObject con PromiseProxyMixin.
import EmberObject from "@ember/object";
import PromiseProxyMixin from "@ember/object/promise-proxy-mixin";

const PromiseObject = EmberObject.extend(PromiseProxyMixin);

// Puoi utilizzare una funzione memoize personalizzata per prevenire richieste multiple per lo stesso utente
const getUser = memoize(username => ajax(`/u/${username}`).then(data => data));
  • Successivamente, dovrai creare queste proprietà calcolate:
  // Promise calcolata
  @discourseComputed("topic")
  posterPromise(topic) {
    const { user } = topic.posters[0];
    return getUser(user.username);
  },

 // Questa CP avvolge la promise con `PromiseObject`
  @discourseComputed("posterPromise")
  posterProxy() {
    const promise = this.get("posterPromise");
    return promise && PromiseObject.create({ promise });
  },

  posterData: reads("posterProxy.content.user"),

  @discourseComputed("posterData")
  isStaff() {
    const posterData = this.get("posterData");
    if (!posterData) return false;
    const { groups = [] } = posterData;
    // Per verificare se l'utente è un membro dello staff, dobbiamo controllare
    // se l'utente appartiene a un gruppo dello staff
    return groups.some(({ name }) => name === "staff");
  }

E nel template topic-list-item.hb(r|s) avresti qualcosa del genere:

  {{#if posterProxy.isFulfilled}}
    {{#if isStaff}}
      // effettua la tua personalizzazione
    {{/if}}
  {{/if}}

Puoi utilizzare isPending per mostrare eventualmente un caricatore.

Spero che questo esempio, sebbene non particolarmente utile, possa aiutarti a capire come funziona il mixin e forse a trovare un modo per utilizzarlo nello sviluppo dei tuoi temi/plugin.

:wave:

4 Mi Piace

Hi @zcuric,

thanks for this very nice write up and the initial PR, there’s definitely things to explore here, in plugins/themes but also in the Discourse codebase. We will see how to apply this pattern and maybe make it simpler in the future :+1:

5 Mi Piace