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

Bob*_*way 0 html javascript checkbox jquery 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());
Run Code Online (Sandbox Code Playgroud)

现在,我很清楚,如果我从我的函数返回true或false,它将起作用.但想象一下我不能那样做(这是有原因的 - 它很复杂).为什么我不能控制JQuery中框的值?

Joh*_*cas 5

根据这个其他stackoverflow答案:

淘汰赛事绑定

并总结为:

允许默认操作

默认情况下,Knockout将阻止事件采取任何默认操作.例如,如果使用事件绑定来捕获输入标记的keypress事件,则浏览器将仅调用处理函数,并且不会将键的值添加到input元素的值.一个更常见的例子是使用click绑定,它在内部使用此绑定,您的处理程序函数将被调用,但浏览器不会导航到链接的href.这是一个有用的默认值,因为当您使用点击绑定时,通常是因为您使用链接作为操纵视图模型的UI的一部分,而不是作为到另一个网页的常规超链接.

但是,如果您确实要继续执行默认操作,只需从事件处理函数返回true即可.

因此默认情况下,除非您返回true,否则将阻止默认事件.

如果它是你想要控制的值,你可以控制下面的内容,它会让你有点长时间思考,并且肯定是黑客,但它确实有效.

在viewmodel上设置一个observable,以确定是否选中了复选框

self.isChecked = ko.observable(false);
Run Code Online (Sandbox Code Playgroud)

在您的虚拟机上设置一个计算的observable,它将用于绑定到复选框选中的值;

self.isCheckedCp = ko.computed(function(){
    return self.isChecked();
});
Run Code Online (Sandbox Code Playgroud)

将计算结果绑定到html中的checked属性:

<input type="checkbox" id="thisFails" data-bind="click: $root.Fails,checked:isCheckedCp" />
Run Code Online (Sandbox Code Playgroud)

更改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);

}
Run Code Online (Sandbox Code Playgroud)

如果您单步执行它,您将看到它何时到达setTimeout console.log('set now'); 该复选框已恢复到您单击它时的状态.

设置self.isChecked然后更新observable并访问计算机并更新复选框显示.

现在我的浏览器及其执行路径的工作原理相当多,但我认为具有零超时值的setTimeout有效地添加了这一段代码,以便在当前(在这种情况下单击)函数之后立即运行,这个链接进入一些细节:

为什么setTimeout(fn,0)有时会有用?

我无法解决为什么设置检查属性通过您的原始jquery在尝试在该超时功能时不起作用.

我希望这实际上对你有所帮助!