我有一个与接口交互的自定义绑定Scribe https://github.com/guardian/scribe,一个内容可编辑的所见即所得编辑器。当编辑器内容发生变化时,它会更新关联的可观察量,并在关联的可观察量发生变化时更新编辑器:
ko.bindingHandlers.editor = {
init: function(element, valueAccessor) {
var $element = $(element),
content = ko.unwrap(valueAccessor()),
scribe;
// create a new editor instance
scribe = new Scribe(element);
// store it for later access in our 'update' handler
$element.data('scribe', scribe);
// set the initial editor content
scribe.setContent(content);
// update the observable whenever the editor changes
scribe.on('content-changed', function() {
var observable = valueAccessor(),
content = scribe.getHTML();
observable(content);
});
},
update: function(element, valueAccessor) {
var $element = $(element),
content = ko.unwrap(valueAccessor());
// update the editor content when the observable changes
$element.data('scribe').setContent(content);
}
};
问题是这样的:
- 用户在编辑器中输入
- 编辑器组件发送“已更改”事件
- 事件处理程序更新可观察的
- 绑定的“更新”处理程序被触发,将更改写回编辑器
通常这没什么大不了的,只是没有必要。但就我而言,editor.setContent
具有将光标位置重置到输入开头的副作用 -你输入的所有内容都会被反转 http://gfycat.com/ShockingRequiredCormorant.
当且仅当可观察对象在应用程序中的其他位置发生更改时,我需要更新编辑器。我正在寻找的是一种避免使用最初源自编辑器本身的更改来更新编辑器的方法。
如何才能最好地避免这些循环更新?
Update:我找到了一种明显的方法来回避眼前的问题 - 在更新处理程序中,只需在进行更新之前将可观察内容与当前编辑器内容进行比较即可:
if ($element.data('scribe').getHTML() !== content) {
$element.data('scribe').setContent(content);
}
如果只是为了避免不必要的更新调用,我仍然对一般答案感兴趣。