I have a view-model where some properties values available for selection are dictated by other properties, this is set via the requires
field:
var clusterOptions = [{
name: "None",
sku: "0",
price: 0,
}, {
name: "Standard MySQL Cluster",
sku: "4101",
requires: ["MySQL1"],
price: 10,
}, {
name: "Enterprise MS SQL Cluster",
sku: "4102",
requires: ["402"],
price: 5,
}, {
name: "NoSQL Sharding",
sku: "4103",
requires: ["403","404"],
price: 10,
}];
The code works (you can see how clicking different options changes dependent options database
and database clustering
): http://jsfiddle.net/g18c/DTdyM/
This code is statically typed, and i am trying to convert this so that arbitrary data (and requires mappings) can be sent from the server viewmodel created with ko.mapping
.
The code to calculate available options for selection is in a helper function (example shown below for two dependent properties from my initial statically defined example):
self.availableDatabases = myutils.ko.createComputedDepdency(this.selectedOs, this.dbOptions);
self.availableClusteringOptions = myutils.ko.createComputedDepdency(this.selectedDb, this.dbClusteringOptions);
I have rewritten my serverData and the only things i need to know form my model are the selected items of the arrays passed in dynamically from the server, in this case it is the options array: selectedServerOption
, selectedOsOption
, selectedDatabaseOption
and selectedClusterOption
I am stuck handling the mapping and unsure how to work with the requiresMapping
array.
How can I handle the mapping of the option fields below?
var serverData = {
options: [serverOptions, osOptions, databaseOptions, clusterOptions],
requiresMappings: [
{target: "selectedOs", options: "dbOptions"},
{target: "selectedDb", options: "dbClusteringOptions"}
]
}
var mappingScheme = {
'options' : {
create: function(options){
console.log("creating sku: " + options.data.sku);
// 1) create dependency using requiresMappings property
// myutils.ko.createComputedDepdency(this.selectedOs, this.dbOptions);
// 2) subscribe to updates
// self.availableDatabases.subscribe(function () {self.selectedDb(self.availableDatabases()[0].sku);});
}
},
// ignore these mappings we don't want to observe them, they are used to define mappings for the creation function above
'ignore' : ["requiresMappings"]
}
var viewModel = ko.mapping.fromJS(serverData, mappingScheme);
My current fiddle is here: http://jsfiddle.net/g18c/DTdyM/5/
After reviewing Automate mapping of dependent properties in knockout answer and the code from @PW Kad, it made sense to write a simple custom mapper.
I chose to write my own mapper over ko.mapping as i couldn't work out how to reference the mapping for the requires (with ko.mapping), and in particular how to make multiple properties from the
create
mapping function (as i could see i could only return a single new property, not multiple as i would need).It works seemingly well, but would appreciate comments or an alternative using ko.mapping just to help my understanding especially if i have reinvented the wheel!
Fiddle is here: http://jsfiddle.net/g18c/DTdyM/26/