I have a particularly tricky problem with ko. I’ll try to explain around some example stuff.
First, here’s the html junk I’m trying to render to. The foreach variable “Appliances” is an array and is a property of the viewModel. The option data is also a property array of the view model. The name of that here is ApplianceTypes.
<table>
<tbody data-bind="foreach: Appliances">
<tr>
<td>
<select data-bind="options: $root.ApplianceTypes, value: $data.ApplianceType.Id, optionsValue: 'Id', optionsText: 'ApplianceTypeDesc'">
</select>
</td>
<td>
<input data-bind="value: UnitNumber" />
</td>
</tr>
</tbody>
</table>
Ok, so now that we have that in mind, here’s the data to fill out ideas a bit better:
var viewModel = {
RequestNumber:37,
UnitNumber:3,
Appliances:[{
Id:2,
ApplianceType:{Id:5, ApplianceTypeDesc:"Water Heating Tankless"},
ServiceApplianceQuantity:"1",
}],
ApplianceTypes:[
{Id:5, ApplianceTypeDesc:"Water Heating Tankless"},
{Id:1, ApplianceTypeDesc:"Dryer"},
{Id:2, ApplianceTypeDesc:"Range"},
{Id:3, ApplianceTypeDesc:"Heating"},
{Id:4, ApplianceTypeDesc:"Water Heating"},
{Id:6, ApplianceTypeDesc:"Fireplace"},
{Id:7, ApplianceTypeDesc:"Make Up Air Heating"},
{Id:8, ApplianceTypeDesc:"BBQ"}
]
}
So, there’s no big problem here yet. I get a UI with a row for each appliance. Each row is a type dropdown filled with appliance types. If I’m just editing what I have, viewModel.Appliances[i].ApplianceType.Id updates and life is good. If I try to add new to my appliances array, the applianceType.Id doesn’t get updated. Here’s the code for that:
function ApplianceTypeViewModel() {
var self = this;
self.Id = ko.observable("5");
self.ApplianceTypeDesc = ko.observable("");
};
function ApplianceViewModel(applianceType) {
var self = this;
self.Id = ko.observable("-1");
self.ApplianceType = ko.observable(applianceType);
self.ServiceApplianceQuantity:"1"
};
viewModel.AddAppliance = function () {
viewModel.Appliances.push(new ApplianceViewModel(new ApplianceTypeViewModel()));
};
Ultimately it would be nice to have the applianceType copied from the array over the Appliances[i].ApplianceType, but honestly, I’m just trying to get the Id to update there. The rest I can do on the server.
If the data exists, it will change everytime. When I create it new (with AddAppliance), the data will not change.
Thanks Everyone!
Just drop the “Id” part in the data binding and your
Appliances[i].ApplianceTypewill be correctly filled with the selected appliance type.value: $data.ApplianceType.Idshould bevalue: $data.ApplianceTypeCheck this jsfiddle for an example of how
valuebinding works http://jsfiddle.net/angelyordanov/gRxMq/.And your code modified to work here http://jsfiddle.net/angelyordanov/vvGgD/.
The way knockout is designed
optionscan be an array of arbitrary javascript objects, not just strings, and the selected item(thevalue) will be one of those objects. That is why you have theoptionsTextbinding, to specify what is the display text for an option.