我想了解为什么在以下代码中将包含 div 制作为可拖动的 jQuery UI 会改变 Knockout JS 数据绑定(bind)的行为。
在第一个 div(可拖动)中,对输入框中的文本进行更改并立即单击“保存”不会导致更改反射(reflect)在可观察到的内容中。在第二个 div(不可拖动)中,更改反射(reflect)在可观察中:
<div id='draggable'>
<h3>Draggable</h3>
<input data-bind='value: detail'></input>
<span data-bind='click: saveEdit'>Save</span>
</div>
<div id='fixed'>
<h3>Fixed</h3>
<input data-bind='value: detail'></input>
<span data-bind='click: saveEdit'>Save</span>
</div>
具有以下支持 Javascript:
VM = {
detail: ko.observable('Cat'),
saveEdit: function(){
alert(this.detail());
}
};
$(document).ready(function() {
$("#draggable").draggable();
ko.applyBindings(VM);
});
您可以在此 jsFiddle 中查看正在运行的代码:http://jsfiddle.net/NLzg2/
如果您将可拖动输入框中的文本更改为 Cath 并单击“保存”,则警报将显示“Cat”。但是,如果您在固定输入框中执行相同操作,则警报会显示“Cath”。因此,在第二种情况下,Knockout 检测到值发生变化,而在第一种情况下却没有。
我知道我可以通过使用 Knockout valueUpdate 绑定(bind)来强制它在每次按键后更新绑定(bind)的可观察值来达到预期的效果。就像这样:
<input data-bind='value: detail, valueUpdate: "afterkeydown"'></input>
我还知道,如果我将 更改为
我想了解的是为什么会发生这种情况,以及如何实现我想要的效果(即可拖动并且在其中的元素上具有正常的 Knockout 值绑定(bind)),而不必在我的代码中添加 valueUpdate 绑定(bind)或使用按钮来绕过这个问题。
最佳答案
draggable
插件捕获鼠标以提供其功能。因此,当您单击 span
时,插件会处理单击事件,并且 knockout 不会收到通知。
当您使用按钮
时它会起作用,因为按钮被排除在可拖动插件的效果之外。
因此,您需要使用cancel option从draggable
插件中排除您的span
例如在标记类的帮助下:
$("#draggable").draggable({cancel: "input,textarea,button,select,option,.save"});
演示 JSFiddle .
关于jquery - 为什么 jQuery UI 可拖动会干扰 Knockout JS 数据绑定(bind)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18431201/