Reputation: 53
My problem is as follows: I am trying to use a checkbox binding to bind an array of objects to a list of selected objects. My problem is, I would like to bind the entire object to the list, as follows:
<div data-bind="foreach: items">
<div>
<input type="checkbox" data-bind="checked: $parent.selectedItems, value: $data">
</div>
</div>
Where items is the list of objects to be bound to the selectedItems observable array.
However, to check if the value is "checked", I would like to compare individual object properties. The reason for this is that I am gathering objects from different sources, and some represent the same object, but they are not entirely identical. Furthermore, I need to use certain sub-properties of the selected objects in other functions, so I need the entire object to be bound to the observable array.
Thanks in advance for any suggestions!
Upvotes: 0
Views: 1643
Reputation: 245
If you dig into the knockout api you can see then when the 'checked' parameter is an array, the binding handler determines if the value is in the array as such:
element.checked = ko.utils.arrayIndexOf(modelValue, checkedValue()) >= 0;
Typically checkedValue() will be set to the item in the options, having the same value as '$data':
var list = ko.observableArray({ value: "One" }, { value: "Two" });
var objectsInList = ko.observableArray(list[0]);
In an options binding like this, in which checkedValue is not specified, the value of $data will be the object:
<select data-bind="options: list, checked: objectsInList">
I didn't specify checkedValue, and therefore in the checked binding handler it will do the arrayIndexOf() operation based on object reference.
What you want to do is specified in the knockout documentation: http://knockoutjs.com/documentation/checked-binding.html
You can set checkedValue in the data-bind parameters like this:
var list = ko.observableArray({ value: "One" }, { value: "Two" });
var objectsInList = ko.observableArray("One");
<select data-bind="options: list, checked: objectsInList, checkedValue: 'value'">
If you want to handle multiple object parameters I think you would need to write your own binding handler.
Upvotes: 1
Reputation: 380
You can use functions in bindings.
<input type="checkbox" data-bind="checked: isChecked($data), ...">
Just keep in mind bindings wrap your code into computed and that's how you get auto ui refresh. This means Knockout may not update ui when you expect it too.
But, really, you need to have consistent data in your view model.
Upvotes: 1
Reputation: 2852
change your html to
data-bind="foreach: { data: items, as: 'item'}">
<div>
<input type="checkbox" data-bind="checked: item.checked, value: item.value">
</div>
</div>
Structure your items as
this.items = ko.observableArray([
{checked: true1, value : value1},
{checked: true2, value : value2},
{checked: true3, value : value3},
])
Of course in real life you don't have variables called true1, value1 etc, that would be json data returned from an API
Note: to avoid problems with this
you probably want at the start of your viewModel
`var self = this`
and use
`self.items = `
Upvotes: 0