4

我想了解为什么在以下代码中将包含 div 的 div 变成可拖动的 jQuery UI 会改变 Knockout JS 数据绑定的行为。

在第一个 div(可拖动)中,对输入框中的文本进行更改并立即单击 Save 不会导致更改反映在 observable 中。在第二个 div(不可拖动)中,变化反映在 observable 中:

<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 绑定来强制它在每次按键后更新绑定的 observable 来达到预期的效果。像这样:

<input data-bind='value: detail, valueUpdate: "afterkeydown"'></input>

我也知道,如果我将 <span> 更改为 <button> 我会得到我期望的行为。

我想了解的是为什么会发生这种情况,以及如何实现我想要的效果(即可拖动并在其中的元素上具有正常的 Knockout 值绑定),而不必在我的代码中添加 valueUpdate 绑定或使用按钮绕过这个问题。

4

1 回答 1

5

draggable插件捕获鼠标以提供其功能。所以当你点击你span的插件时,你会处理点击事件,并且不会收到通知。

它在您使用 a 时起作用,button因为按钮被排除在可拖动插件的效果之外。

因此,您需要使用取消选项span将您从插件中排除,例如在标记类的帮助下:draggable

$("#draggable").draggable({cancel: "input,textarea,button,select,option,.save"});

演示JSFiddle

于 2013-08-25T17:36:13.197 回答