Knockout点击绑定到复选框可防止jQuery控制值

时间:2014-01-16 11:52:39

标签: javascript jquery html checkbox knockout.js

如果您在表单上有一个复选框,使用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中控制框的值?

1 个答案:

答案 0 :(得分:5)

根据其他stackoverflow回答:

knockout event binding

并总结为:

  

允许默认操作

     

默认情况下,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属性不起作用。

我希望这对你有所帮助!