1

I am doing an experiment with Knockout, here's the JSFiddle

Radio button has a data-bind to the enableMe property of the View Model. If I click on the radio button, it updates the enableMe property and 'checked' data-bind gets triggered.

What I am trying to do is that, when I change the checked attribute of the radio button (on button click event) and see whether the View Model changes. It does not change.

Why is that? Need to know how knock out works in this scenario.

var ViewModel = function() {   
    
    this.enableMe = ko.observable(false);    
};
 
var myVM = new ViewModel();
 
ko.applyBindings(myVM); 

function clickme() {
   //Changing the checked state does not change VM
   document.getElementById("myradio1").checked = true;
   //Changing the VM works
   //myVM.enableMe(true);
   
   alert("Alert Message OnClick");
}
<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>
EnableMe: <input id="myradio1" type="radio" data-bind='checked: enableMe'/><br/>
Enable status: <span data-bind='text: enableMe'></span>
<br/>
<button id="button1" onclick="clickme();">Click To Disable</button>
Jeroen
  • 60,696
  • 40
  • 206
  • 339
Dhanuka777
  • 8,331
  • 7
  • 70
  • 126
  • 2
    When usign KO you should not manipulate the DOM manually. You should just update your vm with `myVM.enableMe(true);` – nemesv Jun 18 '16 at 12:53

1 Answers1

1

Several problems:

  1. Don't manipulate DOM when using KO. Manipulate the view model instead, let KO handle updating the DOM for you.
  2. You have a radio button input (without a value attribute!) but seem to want to bind a boolean, which would require extra work.
  3. You use onclick attributes where there's also a click binding handler.

If you insist on ignoring 1 and manipulate the DOM yourself, do so in a way where KO will get notified of the change. Since you use jQuery anyways I recommend using its API for triggering events on the inputs. Here's a demo fixing/working around problem 2 and 3:

var ViewModel = function() {
  this.enableMe = ko.observable(false);
};
 
var myVM = new ViewModel();
 
ko.applyBindings(myVM); 

function clickme() {
  // This is NOT recommended! Check the second example.
  $("#mycheck1").trigger("click");
}
pre { font: 11px consolas; padding: 5px; background: #fafafa; border: 1px solid #ddd; }
<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>

EnableMe: <input value="true" id="mycheck1" type="checkbox" data-bind='checked: enableMe'/><br/>
Enable status: <span data-bind='text: enableMe'></span>
<br/>
<button id="button1" data-bind="click: clickme">Click To Toggle</button>
<hr>
<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>

However, you should use an approach like this:

var ViewModel = function() {
  var self = this;
  
  self.enableMe = ko.observable(false);
  
  self.clickme = function() {
    self.enableMe(true);
  }
};
 
var myVM = new ViewModel(); 
ko.applyBindings(myVM);
pre { font: 11px consolas; padding: 5px; background: #fafafa; border: 1px solid #ddd; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>

EnableMe: <input value="true" id="mycheck1" type="checkbox" data-bind='checked: enableMe'/><br/>
Enable status: <span data-bind='text: enableMe'></span>
<br/>
<button id="button1" data-bind="click: clickme">Click To Toggle</button>
<hr>
<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>
Community
  • 1
  • 1
Jeroen
  • 60,696
  • 40
  • 206
  • 339