Итак, ситуация такая. Я использую TinyMCE WYSIWYG и определяю пользовательский компонент для редактора, чтобы выбрать изображения из галереи миниатюр.
Процесс выглядит следующим образом:
- Пользователь выбирает пользовательский параметр.
- TinyMCE имеет конфигурацию, которая принимает обратный вызов для обработки событий этой кнопки.
- Обратный вызов предоставляется из родительского компонента в качестве входа. Tiny устанавливает это в конфигурации.
- Вызывается обратный вызов и привязывается к родительскому компоненту.
- Родительский компонент отвечает за открытие дочернего компонента, который содержит изображения.
- Этот компонент ленив в том, что изображения открываются, загруженные Родителем , если пользователь когда-либо открывает средство выбора изображений.
- Мысль о том, что компонент не ' необходимо повторно визуализировать изображения каждый раз
- Когда дочерний компонент (Image Picker) открыт и пользователь выбирает изображения, существует кнопка, связанная с событием Output, родительским элементом которого является используется для скрытия / отображения дочернего компонента.
- Теперь у дочернего компонента есть список изображений, которые необходимо вставить в содержимое статьи.
- Родительскому компоненту нужно дождаться, пока эти данные будут всплыть. и затем передайте эти данные для визуализации редактором TinyMCE, чтобы их можно было внедрить в контейнер содержимого.
Моя проблема заключается в том, что когда я подошел к этой проблеме с помощью BehaviourSubject. Каждый раз, когда пользователь выполнял выбор, он повторял бы n раз, где n - это количество раз, когда пользователь открывал средство выбора изображений
Я немного расстраивался, потому что мне не хватает фундаментальных знаний о Rx JS по общему признанию.
Таким образом я в конечном счете вернулся к использованию обратных вызовов от AZ.
Модуль TinyMCE принимает функцию CallbackFunction в качестве входа
@Input() imageSelectCallback: CallableFunction;
Затем он устанавливается на обработчик обратного вызова в конфигурации TinyMCE. Я предварительно настроил действие для того, что происходит после выбора изображений в конфигурации Tiny.
editor.ui.registry.addButton('customDateButton', {
icon: 'gallery',
tooltip: 'Insert Image',
onAction: () => {
const writeContent = editor.insertContent.bind(editor);
const argument = this.imageSelect;
this.imageSelectCallback(writeContent, argument);
},
onSetup(buttonApi) {
const editorEventCallback = function(eventApi) {
buttonApi.setDisabled(eventApi.element.nodeName.toLowerCase() === 'time');
};
editor.on('NodeChange', editorEventCallback);
/* onSetup should always return the unbind handlers */
return function(_buttonApi) {
editor.off('NodeChange', editorEventCallback);
};
}
});
Этот входной обратный вызов принимает как tinyCallback. Это в основном то, что нужно Тини. Что означает запись изображения в тег img в текстовом поле редактора.
imageSelectCallback(tinyCallback, editorFunc) {
this.selectingImage = true;
if (!this.availableImages) {
this.loadThumbnails();
}
const tinyCallbackHandler = data => {
data.forEach(image => {
tinyCallback(editorFunc(image));
});
};
this.picker.ready().then(() => console.log('bla'));
this.picker.setCallback(tinyCallbackHandler);
}
Но это, конечно, зависит от дочернего компонента, чтобы можно было передавать изображения обратно.
В дочернем компоненте у меня есть атрибут обратного вызова, который вызывается, когда пользователь подтверждает свой выбор в дочернем компоненте.
setCallback(func: CallableFunction) {
this.callback = func;
}
И метод обработки готовой части
done() {
this.captured = [];
Object.keys(this.capturedKeys).forEach(key => {
this.captured.push(this.images[key]);
});
this.selected.emit(this.captured);
this.callback(this.captured);
this.ready();
this.captured = [];
this.capturedKeys = {};
this.resetThumbnails();
}
Излучение в основном просто для того, чтобы скрыть компонент от просмотра.
Я делаю что-то не так с самого начала, что обратные вызовы - мой единственный ответ здесь? Я пытался сделать код многократно используемым таким образом, чтобы вы могли просто передать любую функциональность для этой кнопки, в зависимости от приложения, и она будет вести себя так, как вы определяете, но по-прежнему правильно отображать изображения.
Можно ли добиться того же более чистым способом, используя Promises или Observables?
EDIT: Почему мой BehaviourSubject / Subject / ReplaySubject повторяется n раз для каждого вызова .next (images), когда я подписываюсь на него?