我的看法有以下几点:

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

打字时,其行为符合我的预期。但我使用 WMD / Pagedown 编辑器单击一个按钮,将内容添加到该字段,就像您创建/更新帖子时 StackOverflow 的帖子内容框一样。

如果我只是单击一个按钮(添加星号或括号等)并且不键入任何内容,则该值永远不会在 content 可观察到的。

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

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

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

有帮助吗?

解决方案

这是使用 自定义绑定. 。我针对一个实施了 TinyMCE <textarea> 用这个方法成功了。

您观察到的问题是,通过单击工具栏上的按钮进行的​​操作正在引发事件 Markdown.Editor 这会改变基础资产的价值 <textarea> 没有 change 事件被触发,Knockout 当然依赖该事件来通知其订阅者。

我的解决方案实现了自定义绑定,以确保所见即所得编辑器引发的事件反映在视图模型中。具体来说,要确保该值始终是最新的并保持 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 后,这里是从您的 fork 中获取的自定义绑定 JSFiddle

ko.bindingHandlers.wysiwyg = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel) {
        editor.hooks.chain("onPreviewRefresh", function () {
            $(element).change();
        });
        editor.run();
    }
};
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top