简体   繁体   中英

Not able to trigger Knockout data-bind using jQuery

I am writing a plugin using jQuery and knockout. I have two radio buttons. I am using knockout data-bind to check and uncheck the radio button. The problem is that when I am trying to uncheck the radio button on click of another button using jQuery, it is not updating bind observable property .

<input  type="radio" data-bind="checked: selectedVal" name="1" value="fixedPrice"/>  Fixed Price
 <input class="hn" type="radio" data-bind="checked: selectedVal" name="1" value="allowBiding"/> Allow Biding
<pre data-bind="text:ko.toJSON($data,null,2)"></pre>
<input type="button" id="button" value="Click Me" />

 var onClick = function() {
   $('.hn').prop('checked', true);

};

$('#button').click(onClick);

var ViewModel = function () {
    var self = this;
    self.selectedVal = ko.observable("fixedPrice");
    self.selectedVal.subscribe(function (val) {
       console.log(val)
    });
};

ko.applyBindings(new ViewModel());

Please find this jsfiddle below with more details.

Welp! Don't mix KO and jQuery in this way. You're fighting Knockout, not using it. See this earlier answer I wrote for a very similar situation and extended explanation.

Note that this is certainly not a bug, jQuery will by default not trigger events on DOM changes like that. If you insist on mixing KO and jQuery this way, be sure to notify others like this:

 ko.applyBindings({ isChecked: ko.observable(false), onClick: function() { $('.hn').prop('checked', true); $('.hn').trigger('click'); } }); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 1. The radio button: <input type="radio" class="hn" data-bind="checked: isChecked"> <br> 2. Trigger it with jQuery: <button data-bind="click: onClick">trigger</button> <hr> Debug info:<br><textarea data-bind="text: ko.toJSON($root)"></textarea> 

jQuery and Knockout are fighting over control of the view. If you're going to use a viewmodel, use the viewmodel and do not manipulate the DOM except through the viewmodel. You have a viewmodel element that controls the radio buttons, you just need to set it. Knockout provides a click binding, so you don't need jQuery to attach that, either.

 var ViewModel = function () { var self = this; self.selectedVal = ko.observable("fixedPrice"); self.selectedVal.subscribe(function (val) { console.log(val) }); self.setSelected = function () { self.selectedVal('allowBiding'); }; }; ko.applyBindings(new ViewModel()); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <input type="radio" data-bind="checked: selectedVal" name="1" value="fixedPrice" />Fixed Price <input type="radio" data-bind="checked: selectedVal" name="1" value="allowBiding" />Allow Biding <pre data-bind="text:ko.toJSON($data,null,2)"></pre> <input type="button" value="Click Me" data-bind="click:setSelected" /> 

It looks like a bug. However, you can try to invoke the native click handler so the observable will be updated.

$('.hn').triggerHandler('click');

Or

$('.hn')[0].click();

Here is a JsFiddle Demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM