I'm having an issue with knockout js and mapping plugin with a hierarchical view model
My viewmodel is structured somewhat like this:
VM = {
members:[
{
name:"name 1",
volunteering:[{...},{...},{...}]
},
{
name:"name 1",
volunteering:[{...},{...},{...}]
}
]
}
Each member is in a tab, and each tab has a grid of volunteering activities. Clicking on an item in the grid pops up a dialog box to edit the volunteering activity. At this point I clone the object to facilitate 'cancel edit' functionality
var Volunteer = {};
var koContext=ko.contextFor(this);
Volunteer = ko.mapping.toJS(koContext.$data); //plain js volunteer
Volunteer.index=koContext.$parent.EventVolunteers().indexOf(koContext.$data); //index of volunteer in member volunteer array
ko.applyBindings(ko.mapping.fromJS(Volunteer),$("#dialog-EditVolunteer")[0]); //bind new volunteer obj to dialog
Up to this point seems ok, clicking save on the dialog causes the issue.
var volunteer = ko.mapping.toJS(ko.contextFor(this).$data);
ko.mapping.fromJS(volunteer,{},ko.contextFor(currentTab).$data.EventVolunteers()[volunteer.index]);
At this point the properties get updated in the viewmodel, but not in the grid on the main screen.
It appears ko.mapping.fromJS is replacing the observable rather than updating it.
My eventual solution in this case was to set the properties on the original VM, with the edited values from the 'cloned' viewmodel.
For new projects however, I now use a knockout plugin
I'm not certain I wholly understand exactly what you're doing.
But I was attempting to do undo functionality in a list of items, and I used this on the array:
I get the new data as an argument of the click handler.
When I store the original, I basically have this:
The "Emails" are the objects I'm editing. I only store the original data, not the observable. That allowed me to use replace. I'm not certain how correct that is, per se, but canceling works for me.
Personally I'm a fan of creating models like so. The abstraction here just makes more sense.