简体   繁体   中英

KnockoutJS Binding a checkbox with both “checked” and “click” bindings causes unexpected behavior

here is the code I've been working on.

Javascript:

function ViewModel() {
  var self = this;

    self.isChecked = ko.observable(false);

  self.testing = function(){
    console.log("hello from testing");
  }
}

var app = new ViewModel();

ko.applyBindings(app);

And here's the html:

<div>
  <div>
    <button data-bind="click: testing" type="button">Something</button>
    <input data-bind="checked: isChecked, click: testing" type="checkbox" />
    <input data-bind="checked: isChecked" type="checkbox" />
  </div>
</div>

What I'm looking to accomplish is that I want a checkbox, whose value is data-binded to a variable in my model and updates accordingly. And at the same time, whenever a user clicks the checkbox to change its boolean value, I want a function to be executed AFTER the value is changed in the model and the checkbox is updated.

I have two buttons data-binded to the same value just for testing purposes. When I click the checkbox that is binded with click to testing , its checkmark doesn't change, but the function executes correctly. However, the other checkbox DOES indeed update to reflect the changes in the model when the button is clicked.

What is happening that causes this behavior, and how could I write a better solution to achieve what I'm looking for?


EDIT: So apparently, by adding a return true; to the function, I managed to... arrive at the intended behavior?

function ViewModel() {
  var self = this;

  self.isChecked = ko.observable(false);

  self.testing = function(){
    console.log(self.isChecked());
    console.log("hello from testing");
    console.log(self.isChecked());

    return true;
  }

}

var app = new ViewModel();

ko.applyBindings(app);

The question is then, why does this happen, and is it safe?

This seems like an XY problem . So, in addition to what @Tomalak mentioned, if you want to trigger a function when the checkbox value is changed, you can subscribe to the isChecked observable

 function ViewModel() { var self = this; self.isChecked = ko.observable(false); self.isChecked.subscribe(function(newValue) { // this gets executed every time "isChecked" changes console.log(self.isChecked()); console.log(newValue); }); } ko.applyBindings(new ViewModel()); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script> <input data-bind="checked: isChecked" type="checkbox" /> 

The advantage of using subscribe over click binding is that, this function gets triggered even when you set the value of checkbox programmatically like this self.isChecked(false)

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