Trying to get basic Knockout click binding set up, as per the example below:
<button id="btn-a" class="btn" data-bind="css: {'btn-primary':mode() == 'manual'}, click: $root.mode('manual')">Manual</button>
<button id="btn-b" class="btn" data-bind="css: {'btn-primary':mode() == 'automatic'}, click: $root.mode('automatic')">Automatic</button>
<label>MODE: </label><span data-bind="text:mode()"></span>
<script>
$(function () {
var TestModel = function() {
var self = this;
this.mode = ko.observable('manual');
};
var testModel = new TestModel();
window.testModel = testModel;
ko.applyBindings(testModel);
});
Fiddle: http://jsfiddle.net/aq85wk65/
However, running into two issues:
- The binding causes the
mode()
value to start out as
'automatic', even though we explicitly initialize it to 'manual'.
- Whenever a button is clicked, the javascript console shows:
Uncaught TypeError: h.apply is not a function
You need to wrap your click handlers in function:
http://jsfiddle.net/aq85wk65/1/
<button id="btn-a" class="btn" data-bind="css: {'btn-primary':mode() == 'manual'}, click: function(){$root.mode('manual')}">Manual</button>
see http://knockoutjs.com/documentation/click-binding.html
The problem is that your click
handler is invoking the function instead of using its reference.
That's why you're ending up with mode
being auto
, because click: $root.mode('automatic')
is setting the observable value.
Try this instead:
click: $root.mode.bind($root, 'manual')
Either the .bind
answer or the function() {}
answer will work; but generally I prefer to avoid defining functions in my views where possible, and instead move that logic to the ViewModel.
So another option, and the one I'd probably go with in this case is to define a viewModel.setToManual()
function and a viewModel.setToAutomatic()
function.
Then the binding handler would just be
click: setToAutomatic
Not only is that cleaner in the view, but it protects the view against changes to the ViewModel's structure as well, as long as the behavior of setToAutomatic
(and probably a comparable isAutomatic
) are preserved.