如果您在表单上有一个复选框,使用Knockout点击一个函数,它似乎会覆盖复选框状态的编程控件。
这里有一个表示问题的小提琴: http://jsfiddle.net/Y5Zk8/
代码:
<input type="checkbox" id="thisFails" data-bind="click: $root.Fails" />
<label for="thisFails">This Fails</label>
var SimpleModel = function() {
this.Fails = function() {
alert('clicked');
$('#thisFails').attr('checked', true);
}
};
ko.applyBindings(new SimpleModel());
现在,我很清楚,如果我从我的函数中返回true或false,它将会起作用。但想象一下我不能那样做(这是有原因的 - 它很复杂)。为什么我不能在JQuery中控制框的值?
答案 0 :(得分:5)
根据其他stackoverflow回答:
并总结为:
允许默认操作
默认情况下,Knockout会阻止事件采取任何默认值 行动。例如,如果您使用事件绑定来捕获 输入标签的按键事件,浏览器只会调用你的 处理程序函数,不会将键的值添加到输入 元素的价值。一个更常见的例子是使用点击绑定, 在内部使用此绑定,您的处理程序函数将在其中 被调用,但浏览器不会导航到链接的href。这个 是一个有用的默认值,因为当你使用点击绑定时,它是 通常是因为您使用链接作为UI的一部分 操纵您的视图模型,而不是作为到另一个Web的常规超链接 页。
但是,如果您确实要让默认操作继续,请返回 从您的事件处理函数中获取true。
因此默认情况下,除非您返回true,否则将阻止默认事件。
如果你想要控制它的值,你可以控制下面的内容,它会让你有点长时间的思绪和明确的黑客攻击,但它确实有效。
在viewmodel上设置一个observable,以确定是否选中了复选框
self.isChecked = ko.observable(false);
在你的虚拟机上设置一个计算的observable,它将用于绑定到复选框选中的值;
self.isCheckedCp = ko.computed(function(){
return self.isChecked();
});
将计算结果绑定到html中的checked属性:
<input type="checkbox" id="thisFails" data-bind="click: $root.Fails,checked:isCheckedCp" />
更改Fails函数以包含将在失败函数完成后立即运行的超时,并在该函数中,设置基础isChecked observable的值(在示例中它只是切换当前值)
self.Fails = function(e) {
console.log('e',e.isChecked());
alert('arse');
console.log( $('#thisFails'));
setTimeout(function(){
console.log('set now');
//this works
self.isChecked(!self.isChecked());
//still doesn't work with the set timeout
$('#thisFails').attr('checked', true);
console.log('e',e.isChecked());
}, 0);
}
如果您单步执行它,您将看到它何时到达setTimeout console.log('set now');该复选框已恢复到您点击它时的状态。
设置self.isChecked然后更新observable并访问计算机并更新复选框显示。
现在我的浏览器及其执行路径的工作原理相当多,但我认为具有零超时值的setTimeout有效地添加了这一段代码,以便在当前后立即运行(在这种情况下单击)功能,这个链接有一些细节:
Why is setTimeout(fn, 0) sometimes useful?
我无法理解为什么在尝试使用该超时功能时,通过原始jquery设置checked属性不起作用。
我希望这对你有所帮助!