3

在我看来,我有以下几点:

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

键入时,其行为与我预期的一样。但是我正在使用 WMD / Pagedown 编辑器来单击一个向字段添加内容的按钮,就像您创建/更新帖子时 StackOverflow 的帖子内容框一样。

如果我只是单击一个按钮(添加星号或括号等)并且不输入任何内容,则该值永远不会在contentobservable 中更新。

我确实有一个save按钮,可以在保存数据之前通过指定要更新的输入元素来触发“同步”,但我不知道这是否可能。处理这种情况的正确方法是什么?

更新:Jsfiddle 演示问题:http: //jsfiddle.net/BcuLq/

更新 2:这种行为也发生在我用来用字符串填充输入的 datetime 日期选择器上。我可以应用于所有以编程方式填充的输入的任何通用解决方案都是理想的,尽管我不确定这是否是解决此问题的合理方法。

4

1 回答 1

4

这是使用自定义绑定的真正用例。<textarea>我用这种方法成功地实现了 TinyMCE 。

您正在观察的问题是您通过单击工具栏上的按钮进行的​​操作正在引发事件,这会在不触发事件的情况下Markdown.Editor改变底层的值,当然 Knockout 依赖于它来通知它的订阅者。<textarea>change

我的解决方案实现了自定义绑定,以确保所见即所得编辑器引发的事件反映在视图模型中。具体来说,要确保该值始终是最新的,并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();
    }
};
于 2013-11-18T13:19:18.690 回答