Knockout.Js没有检测到以编程方式更改的复选框状态

我有一个简单的复选框,其值通过一些基础设施进行调整,我正在写入localStorage中的持久状态。 我知道这通常可以通过设置viewModel来完成,但基础结构不知道任何敲除绑定并且无法访问它们。

我不认为这会是一个问题,因为我认为淘汰赛正在关闭’更改’事件,但是$checkbox.prop('checked', true).trigger('checked')无法触发我的观察。 即使直接使用点击事件也不能满足我的需求。

敲门线会发生什么事? 如何让它读取控件的状态?

jsbin在这里展示了这种奇怪的行为 。 尝试直接选中复选框,然后单击按钮。

我发现了一种更好的方法。 只需将此代码放入domready事件中:

  $("input:checkbox").bind('change', function () { $(this).triggerHandler('click'); }); 

敲除绑定并不像你想象的那样真正起作用。

查看: http : //knockoutjs.com/documentation/custom-bindings.html

这是一个你可以使用的解决方案,没有jQuery,没有自定义绑定。

你的HTML将保持不变。

 var m = { isChecked: ko.observable(false), infrastructureUpdatesCheckbox: function() { this.isChecked( this.isChecked() === true ? false : true); } }; ko.applyBindings(m); 

您应该通过您的视图模型更改复选框’已检查状态:

  var m = { isChecked: ko.observable(false) //,infrastructureUpdatesCheckbox: function() { //$chk = $(':checkbox'); //$chk // .prop('checked', !$chk.prop('checked')) // .trigger('change'); //this.isChecked(!this.isChecked()); // this - is your view model } }; 

这是更新版本:

 function InfrastructureUpdatesCheckbox(){ var $cb = $(':checkbox'); var cb = $cb[0]; cb.checked = !cb.checked; // manually change checked status $cb.triggerHandler('click'); // run all event handlers bound to 'click' event } 

我想这个问题只与复选框(单选按钮)有关。 手动触发事件时,其他控件应正确运行。

您可能已经找到了问题的解决方案,但这可能会帮助其他人。

我有完全相同的问题。 我所做的是使用pub-sub模式并让我的组件触发自己的更改事件。 您可以做的是让需要更新模型的基础架构组件实例订阅该事件,然后更新您的模型。 更好的是,您的模型可以订阅事件,这样您的模型就可以了解基础架构组件,而不是相反

这样您的基础架构组件就不需要了解ko,您可以在其他任何地方重复使用它。 我相信如果您计划重新使用该组件,那么在找到其他用途之前,这只是时间问题。

希望这有帮助(抱歉没有代码,因为我不能在SO上发布客户端代码,但如果有人想要一个例子就这么说,我会做一个jsfiddle来说明。

在我的情况下,这结果与jquery bug有关。 我带着github淘汰赛问题跟踪器来跟踪这个问题; 看到这里 。

最终我最终在我的组件中执行此操作:

 var isjQueryOld = /^(0|1)\.[0-8]\./.test($.fn.jquery); // <=1.8.* var toggleCheckbox = isjQueryOld ? jQueryOldToggleCheckbox : function($el) { $el.trigger('click') } //https://github.com/knockout/knockout/issues/987 function jQueryOldToggleCheckbox($el) { //This should be simple right? See http://stackoverflow.com/a/8595601/5056 //and "simulating events to adjust knockout models" jasmine spec //all this is nessessary to get everything working with knockout var changeTo = !$el.prop('checked'); if(changeTo) $el.attr('checked', true); else $el.removeAttr('checked'); $el.trigger('click'); $el.prop('checked', changeTo); } 

在我的代码中

  toggleCheckbox($el); 

我不知道敲门的事情是什么,你可能会涉及到源本身并想出来,但一种解决方案是使用自定义绑定 。 在自定义绑定的init ,您可以为要捕获的任何事件(例如已changed )设置所需的处理程序,并使用它来强制绑定以运行update

我今天花了好几个小时进入点击循环,点击和点击方法,尝试ko.observable,pureComputed写入甚至基础设施更新检查框没有成功太长时间向任何支付我的工作的人解释为什么我无法检查该死的淘汰赛中的单选按钮。 不幸的是我的上下文(带有购买插件的Magento 2 checkout)不允许我实现有效的视图模型,所以最后我设法用简单的黑客来解决问题,添加第二个输入类型=“radio”并在点击时显示:

 selectRadioPayment: function (obj, event, method) { this.selectPaymentMethod(obj, event, method); $('.ko-payment-selector').show(); $('#p_method_' + method).hide(); $('#p_method_' + method).closest('.radio-payment-selector').show(); }, renderedPaymentMethods: function() { if(quote.paymentMethod) { var selectedMethod = quote.paymentMethod().method; $('#p_method_' + selectedMethod).hide(); $('#p_method_' + selectedMethod).closest('.radio-payment-selector').show(); } },   

我希望有一天能帮助别人。