Я хочу использовать сервис в компоненте темы, который я создаю. Если сервисы доступны только в плагинах, я могу создать и плагин. Цель — соединить два разных выхода плагинов: нажать кнопку в одном выходе, и чтобы нажатие этой кнопки было перехвачено другим выходом.
Как правильно зарегистрировать сервис в Discourse? Я следовал теме здесь и связанному коду плагина на GitHub, но не могу заставить это работать.
Кажется, недостающее звено в том, что мой компонент темы не распознает сервис. (Попробовал также в плагине, результат тот же).
Вот код, который я пробовал:
javascripts/discourse/services/great-stuff.js:
import Service, { inject as service } from "@ember/service";
export default class GreatStuffService extends Service {
call() {
console.log('вы вызвали это')
}
}
Возможно, стоит посмотреть, как написаны другие сервисы. Мне кажется, что синтаксис x extends y пока не работает в версии Ember, которую использует Discourse.
Также можно обратиться к API appEvents для обмена данными между двумя компонентами.
Проблема здесь в том, что «connector» не является объектом EmberObject, поэтому в него нельзя внедрять зависимости. Вместо этого вам нужно создать компонент Ember и внедрить их туда.
Шаблон вашего «connector» будет выглядеть примерно так:
{{my-component-name}}
Вот пример того, как это реализовано в плагине whos-online:
@david: большое спасибо за это объяснение и примеры кода. С помощью этих примеров мне удалось заставить работать клик по кнопке в компоненте, который вызывает действие в сервисе. Это большой шаг вперёд.
Теперь я пытаюсь разобраться с другой половиной — как, после вызова действия в сервисе, запустить действие в компоненте. Я предполагаю, что это что-то вроде импорта компонента в сервис и вызова функции в этом компоненте (и/или подписки на действие в компоненте). Но я пока не совсем разобрался с синтаксисом.
Вызов метода компонента из сервиса — это не лучшая практика, и в Ember нет простого способа это сделать. Поскольку экземпляров компонента может быть несколько, как сервис узнает, на каком именно нужно инициировать действие?
Тем не менее, иногда необходимо заставить что-то работать в рамках системы плагинов Discourse.
Я рекомендую то же, что и @fzngagan: обратите внимание на appEvents. Это, вероятно, самый чистый способ запускать логику компонента из сервиса.
Мне казалось, что для этого предназначен evented, но я раньше его не использовал. Цель — создать механизм, похожий на IPC, где:
пользователь нажимает кнопку в компоненте A
это нажатие вызывает загрузку данных в компоненте B
Я больше знаком с Angular, где создание сервиса и подписка на него — это общий способ решения таких задач. Но в Discourse лучший способ — это appEvents?
Интересно! Спасибо за уточнение. Я не сторонник Evented — никогда раньше его не использовал, и у меня возникли некоторые трудности с синтаксисом в сервисе Discourse: export default class GreatStuffService extends Service.extends(Evented, {...})
работает не совсем правильно.
Раньше я тоже не использовал appEvents. Могу ли я создать новое событие appEvent в плагине или компоненте темы, чтобы затем подписаться на него? Большинство примеров, которые я нахожу, касаются подписки на уже существующие в ядре Discourse события appEvents.