Обещание или обратный вызов между родительским и дочерним компонентами из начального обратного вызова - PullRequest
0 голосов
/ 29 марта 2020

Итак, ситуация такая. Я использую TinyMCE WYSIWYG и определяю пользовательский компонент для редактора, чтобы выбрать изображения из галереи миниатюр.

Процесс выглядит следующим образом:

  1. Пользователь выбирает пользовательский параметр.
  2. TinyMCE имеет конфигурацию, которая принимает обратный вызов для обработки событий этой кнопки.
  3. Обратный вызов предоставляется из родительского компонента в качестве входа. Tiny устанавливает это в конфигурации.
  4. Вызывается обратный вызов и привязывается к родительскому компоненту.
  5. Родительский компонент отвечает за открытие дочернего компонента, который содержит изображения.
    • Этот компонент ленив в том, что изображения открываются, загруженные Родителем , если пользователь когда-либо открывает средство выбора изображений.
    • Мысль о том, что компонент не ' необходимо повторно визуализировать изображения каждый раз
  6. Когда дочерний компонент (Image Picker) открыт и пользователь выбирает изображения, существует кнопка, связанная с событием Output, родительским элементом которого является используется для скрытия / отображения дочернего компонента.
  7. Теперь у дочернего компонента есть список изображений, которые необходимо вставить в содержимое статьи.
  8. Родительскому компоненту нужно дождаться, пока эти данные будут всплыть. и затем передайте эти данные для визуализации редактором 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), когда я подписываюсь на него?

...