Reputation: 122062
I would like to use the knockout mapping plugin but I need the objects on my model to be properties in themselves (mostly because they need to be substitute-able).
Consider a greatly simplified example with the following model:
{
family: {
patriarch: {
name: "Fred Flintstone", child: "Pebbles"
}
},
allPeople: [
{name: "Fred Flintstone", child: "Pebbles"},
{name: "Wilma Flintstone", child: "Pebbles"},
{name: "Barney Rubble", child: "Bam Bam"}
]
}
Suppose I want to be able to modify the patriarch via a select where the options are allPeople where changing the selection might have many side-effects.
The mapping plugin makes all name properties observable and allPeople an observableArray but in order for my select to work properly the patriarch object itself would have to be observable.
Writing my own crude mapper is all of 13 lines of code but since the mapping plugin is so fully featured I am hoping there's an option or some other way to get this seemingly common scenario working.
Upvotes: 0
Views: 323
Reputation: 5283
How about this? For the select:
<select data-bind="options: allPeople, optionsText: 'name', value: family.patriarch"></select>
And when setting up the mapping, rather than specifying a sub view model for the patriarch property, return an observable using the initial data:
var data = {
family: {
patriarch: {
name: "Fred Flintstone", child: "Pebbles"
}
},
allPeople: [
{name: "Fred Flintstone", child: "Pebbles"},
{name: "Wilma Flintstone", child: "Pebbles"},
{name: "Barney Rubble", child: "Bam Bam"}
]
};
var mapping = {
'patriarch': {
create: function (options) {
return ko.observable(options.data);
}
}
}
var vm = ko.mapping.fromJS(data, mapping);
vm.family.patriarch.subscribe(function(value) {
alert(ko.toJSON(value));
});
ko.applyBindings(vm);
Fiddle here:
Does that work as you need it?
Upvotes: 1