Reputation: 5692
I've got the following code using Knockout.js to display an array of bools as a series of checkboxes:
<table>
<tr data-bind="foreach: Array">
<td><input type=checkbox data-bind="checked:$data"></td>
</tr>
<tr data-bind="foreach: Array">
<td data-bind="text:$data"></td>
</tr>
</table>
<button data-bind="click: toggle0">Toggle Element 0</button>
<script>
var simpleModel = {
"Array" : ko.observableArray([ko.observable(false),
ko.observable(false),
ko.observable(true)]),
"toggle0" : function() {
simpleModel.Array()[0](!simpleModel.Array()[0]());
}
};
ko.applyBindings(simpleModel);
</script>
If you look at http://jsfiddle.net/tP9Dm/3/, you can see that, while the checkboxes respond to changes in the view-model, the view-model doesn't respond to changes in the checkboxes.
According to https://groups.google.com/d/msg/knockoutjs/-dHpOg5ZBPI/1q4iqdTlKvUJ, it looks like $data
is unwrapped by the foreach loop, so data-bind
doesn't know to use it to update the model.
Clearly I can fix this by making the array contain objects instead of simple booleans, but that seems like it should be an unnecessary extra layer of indirection. Is there a simpler way to propagate changes back to the model?
Upvotes: 2
Views: 364
Reputation: 60021
There doesn't seem to be a way to do this, because $data in this case is the unwrapped value.
Even setting up a click handler doesn't work, because the data sent to your handler is also unwrapped.
Bummer. Looks like the only way to do this is to wrap your observable into an object, another layer of indirection.
Upvotes: 1