我认为我有以下内容:
<textarea data-bind="value: content, valueUpdate: 'afterkeydown'"></textarea>
在键入时,行为与我期望的一样。但我正在使用WMD / Pagedown编辑器单击一个向该字段添加内容的按钮,就像创建/更新帖子时StackOverflow的帖子内容框一样。
如果我只是单击一个按钮(添加星号或括号等)并且不输入任何内容,则content
可观察值中的值永远不会更新。
我有一个save
按钮,我可以通过指定要更新的输入元素来保存数据之前触发“同步”,但我不知道是否可能。处理这种情况的正确方法是什么?
更新:Jsfiddle演示问题:http://jsfiddle.net/BcuLq/
更新2:我正在使用日期时间日期选择器来填充输入字符串,这种情况也会发生。我可以应用于所有以编程方式填充的输入的任何通用解决方案都是理想的,但我不确定这是否是一种合理的解决方法。
答案 0 :(得分:4)
这是使用custom binding的真实用例。我用这种方法成功地对<textarea>
实施了TinyMCE。
您正在观察的问题是,通过单击工具栏上的按钮进行的操作会引发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();
}
};