Значение knockoutUpdate не работает с Pagedown?

У меня есть следующее на мой взгляд:

<textarea data-bind="value: content, valueUpdate: 'afterkeydown'"></textarea>

Который при наборе ведет себя так, как я ожидал. Но я использую редактор WMD / Pagedown, чтобы нажимать кнопку, которая добавляет контент в поле, так же, как поле Stackru для публикации сообщений при создании / обновлении публикации.

Если я просто нажимаю кнопку (чтобы добавить звездочки или скобки и т. Д.) И ничего не набираю, значение никогда не обновляется в content наблюдаемым.

У меня есть save Кнопка, которую я мог бы использовать для запуска "синхронизации" перед сохранением данных, указав элементы ввода для обновления, но я понятия не имею, возможно ли это. Как правильно справиться с этой ситуацией?

Обновление: Jsfiddle для демонстрации проблемы: http://jsfiddle.net/BcuLq/

Обновление 2: Такое поведение также происходит с датчиком datetime, который я использую для заполнения ввода строкой. Любое общее решение, которое я могу применить ко всем программно заполненным входам, было бы идеальным, хотя я не уверен, что это разумный способ сделать это.

1 ответ

Решение

Это подлинный вариант использования пользовательского связывания. Я реализовал TinyMCE против <textarea> успешно с этим методом.

Проблема, которую вы наблюдаете, состоит в том, что манипуляции, которые вы выполняете, нажимая кнопки на панели инструментов, вызывают события на Markdown.Editor который изменяет значение базового <textarea> без change событие, которое запускается, на что, конечно, полагается Knockout, чтобы уведомить своих подписчиков.

Мое решение реализует пользовательскую привязку, чтобы гарантировать, что события, вызванные редактором wysiwyg, отражаются в модели представления. В частности, чтобы гарантировать, что значение всегда актуально, а также поддержание dirty флаг в виде-модели. Поскольку я не знаком с плагином Markdown, я включил образец, взятый из моего решения TinyMCE. Принцип будет точно таким же, вам просто нужно применить специфику редактора Markdown.

ko.bindingHandlers.wysiwyg = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel) {
        $(element).tinymce({
            /*** other options excluded for brevity ***/
            setup: function(editor) {
                editor.on('change', function() {
                    valueAccessor()(editor.getContent());
                    viewModel.isDirty = editor.isDirty();
                });
            }
        });
    },
    update: function(element, valueAccessor) {
            $(element).text(valueAccessor()());
    }
};

Наконец, ваша привязка теперь может быть реализована следующим образом;

<textarea data-bind="value: content, wysiwyg: content"></textarea>

ОБНОВИТЬ

После прочтения на PageDown, вот пользовательская привязка, взятая из форка вашего JSFiddle

ko.bindingHandlers.wysiwyg = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel) {
        editor.hooks.chain("onPreviewRefresh", function () {
            $(element).change();
        });
        editor.run();
    }
};
Другие вопросы по тегам