Недавно в ядро Discourse в модулях Ember был добавлен Ember.PromiseProxyMixin.
Это очень полезная миксин-библиотека Ember, которая позволяет выполнять асинхронные запросы и удобно работать с промисами внутри компонентов Ember. Представьте её как React Suspense, но для Ember. Потенциал для разработки тем и плагинов в Discourse огромен.
Вот официальная документация Ember по Ember.PromiseProxyMixin.
Я приведу простой пример того, как эту миксин можно использовать внутри темы Discourse. Допустим, по какой-то причине в компоненте topic-list-item вы хотите стилизовать аватар автора, если он является сотрудником: у аватара должна быть другая рамка.
Где-то в файле topic-list-item.js(.es6) вам потребуется:
- Импортировать
EmberObjectиPromiseProxyMixinи расширитьEmberObjectс помощьюPromiseProxyMixin:
import EmberObject from "@ember/object";
import PromiseProxyMixin from "@ember/object/promise-proxy-mixin";
const PromiseObject = EmberObject.extend(PromiseProxyMixin);
// Вы можете использовать пользовательскую функцию мемоизации, чтобы предотвратить множественные запросы для одних и тех же пользователей
const getUser = memoize(username => ajax(`/u/${username}`).then(data => data));
- Затем вам нужно создать следующие вычисляемые свойства:
// Вычисляемый промис
@discourseComputed("topic")
posterPromise(topic) {
const { user } = topic.posters[0];
return getUser(user.username);
},
// Это вычисляемое свойство оборачивает промис в `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;
// Чтобы проверить, является ли пользователь сотрудником, нужно убедиться,
// что он состоит в группе сотрудников
return groups.some(({ name }) => name === "staff");
}
А в шаблоне topic-list-item.hb(r|s) у вас будет что-то вроде этого:
{{#if posterProxy.isFulfilled}}
{{#if isStaff}}
// выполните вашу кастомизацию
{{/if}}
{{/if}}
Вы также можете использовать isPending, чтобы, например, показать индикатор загрузки.
Надеюсь, этот не самый полезный пример поможет вам разобраться, как работает миксин, и, возможно, подскажет, как вы сможете использовать его в разработке своих тем или плагинов.
![]()