3

I am having a problem getting the knockout model to update when a user uses the PageDown button bar to make changes to the editor text. Any typing, pasting, or cutting works fine but the button bar actions do not.

I have tried adding a hook for onPreviewRefresh to the editor but that never seems to fire.

Here is a Fiddle showing the issue. If you type test into the editor, test will show up in the preview section. However, if you type test into the editor and then use the menu bar to make test bold then the preview section does not see this update until you type another character.

This is the custom binding that I am using to initialize the PageDown editor:

var ME = {};
ME.MarkdownConverter = Markdown.getSanitizingConverter();
ME.MarkdownCounter = 0;

ko.bindingHandlers.markdownEditor = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        ++ME.MarkdownCounter;
        // Create the elements needed for a new PageDown editor.
        $(element).append($('<div id="wmd-button-bar-' + ME.MarkdownCounter + '" class="wmd-button-bar"></div>'));
        $(element).append($('<textarea id="wmd-input-' + ME.MarkdownCounter + '" class="wmd-input"></textarea>'));

        // Make sure the textarea is properly binded up so that the view model is updated.
        var newBindings = { textInput: valueAccessor };
        ko.applyBindingAccessorsToNode($('#wmd-input-' + ME.MarkdownCounter)[0], newBindings, viewModel);

        // Create the editor and apply to the new elements ensuring that we detect all
        // changes from the wmd-button-bar.
        var editor = new Markdown.Editor(ME.MarkdownConverter, "-" + ME.MarkdownCounter);
        editor.hooks.chain("onPreviewRefresh", function () {
            var value = valueAccessor();
            debugger;
            value($('#wmd-input-' + ME.MarkdownCounter).val());
        });
        editor.run();

        return { controlsDescendantBindings: true }; 
    }
};
4

1 回答 1

1

不会触发值更新,因为值是通过编程设置的,不会触发 textarea 的更改事件。

onPreviewRefresh事件未触发,因为没有预览元素。作为一种解决方法,您可以添加元素并将其隐藏:

var ME = {};
ME.MarkdownConverter = Markdown.getSanitizingConverter();
ME.MarkdownCounter = 0;

ko.bindingHandlers.markdownText = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        $(element).addClass('markdown-text');
    },
    update: function(element, valueAccessor, allBindings) {
        var value = valueAccessor();
        var valueUnwrapped = ko.unwrap(value);
        $(element).html(ME.MarkdownConverter.makeHtml(valueUnwrapped));
    }
};

ko.bindingHandlers.markdownEditor = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        ++ME.MarkdownCounter;
        // Create the elements needed for a new PageDown editor.
        $(element).append($('<div id="wmd-button-bar-' + ME.MarkdownCounter + '" class="wmd-button-bar"></div>'));
        $(element).append($('<textarea id="wmd-input-' + ME.MarkdownCounter + '" class="wmd-input"></textarea>'));        
        // if no preview element is found, onPreviewRefresh is not triggered
        $(element).append('<div style="display: none" class="wmd-panel wmd-preview" id="wmd-preview-' + ME.MarkdownCounter + '"></div>');

        var $input = $('#wmd-input-' + ME.MarkdownCounter);

        // Make sure the textarea is properly binded up so that the view model is updated.
        var newBindings = { textInput: valueAccessor };
        ko.applyBindingAccessorsToNode($input[0], newBindings, viewModel);

        // Create the editor and apply to the new elements ensuring that we detect all
        // changes from the wmd-button-bar.
        var editor = new Markdown.Editor(ME.MarkdownConverter, "-" + ME.MarkdownCounter);
        editor.hooks.chain("onPreviewRefresh", function () {
            $input.change();
        });
        editor.run();

        return { controlsDescendantBindings: true }; 
    }
};

var vm = { noteText: ko.observable('') };
ko.applyBindings(vm);

http://jsfiddle.net/vaako62z/3/

于 2014-11-12T11:21:56.993 回答