Reputation: 3243
Got a bit of a conundrum with a knockout observable array being shared across multiple view models.
Basically, I have a layout as follows
Transport
... textbox fields, etc
Selected Passengers:
<!-- ko foreach: allPassengers -->
<input type="checkbox" />
<!-- /ko -->
<button>Add Transport</button>
Holiday
... textbox fields, etc
Selected Passengers:
<!-- ko foreach: allPassengers -->
<input type="checkbox" />
<!-- /ko -->
<button>Add Holiday</button>
Now the selected passengers for each section is being generated from ONE observable array, idea being if a passenger is deleted/altered everything should fall into place automagically.
So something like this
function page() {
// in actuality this passengers array is a computed observable obtained from the passengers section which is not shown here.
this.allPassengers = ko.observableArray([
{
Id: 1,
name = ko.observable('name'),
checked = ko.observable(false)
},
{
.
.
]);
}
function transport() {
// pageVM is a page object
this.allPassengers = pageVM.allPassengers;
this.transportItems = ko.observableArray();
this.addTransport = function() {
this.transportItems.push({
.
.
selectedPassengers: [...]
.
.
});
};
}
function holiday() {
// pageVM is a page object
this.allPassengers = pageVM.allPassengers;
this.holidayItems = ko.observableArray();
this.addHoliday = function() {
this.holidayItems.push({
.
.
selectedPassengers: [...]
.
.
});
};
}
However, when add transport/holiday is clicked, I need a way to determine which checkboxs where checked so I can add the selected passengers.
I have tried to add a checked = ko.observable(false)
property to the passenger item in parent.allPassengers
, but the problem with this approach is if a checkbox is checked in the transport section it will also check it in the holiday section since it is using the same observable array.
Any ideas??
Edit:
Upvotes: 4
Views: 2240
Reputation: 7517
You can use a ko.computed
to return the selected passengers (and here's a fiddle):
var ViewModel = function () {
this.allPassengers = ko.observableArray([
{ name: 'John', selected: ko.observable(false) },
{ name: 'Jane', selected: ko.observable(false) },
{ name: 'Mark', selected: ko.observable(false) }
]);
this.selectedPassengers = ko.computed(function () {
return ko.utils.arrayFilter(this.allPassengers(), function (item) {
return item.selected();
});
}, this);
};
Upvotes: 0
Reputation: 11403
The checked binding works with observable arrays too. So you can simply bind to $parent.selectedPassengers
and specify the value attribute to be the passenger id, like this:
<input type="checkbox" data-bind="attr: { value: id },
checked: $parent.selectedPassengers" />
In each view model you need to have a selectedPassengers
observable array used for binding to the checkbox. And the add function should look like this:
function transport(pageVM) {
....
this.selectedPassengers = ko.observableArray([]);
....
this.addTransport = function() {
this.selectedItems.push({
....
selectedPassengers: this.selectedPassengers()
});
};
};
Upvotes: 4