Reputation: 75
I'm trying to implement some kind of undo feature in my project using KnockoutJS. For this purpose, I'm using this extender:
ko.extenders.trackChange = function (target, track) {
if (track) {
target.isDirty = ko.observable(false);
target.originalValue = target();
target.subscribe(function (newValue) {
// Push to "states" array a JS representation of the viewModel
// so I can get a stack of changes
states.push(ko.toJS(track.myViewModel));
target.isDirty(newValue != target.originalValue);
target.originalValue = newValue;
});
}
return target;
};
Then I apply the extender to an object into the viewModel:
this.myViewModel = {
label: ko.observable("Label").extend({ trackChange: this });
}
And when I want to undo an action, I do this:
ko.applyBindings(ko.mapping.fromJS(states[statesPointer]));
This is ok in order to get the old values, but the extend function in the observable is lost so new changes are not saved in the "states" stack.
Suggestions?
Thanks in advance, Elian.
Upvotes: 1
Views: 820
Reputation: 3907
I think you should not create new model instance performing undo op, but just update observable properties of existing model:
// you do:
// ko.applyBindings(ko.mapping.fromJS(states[statesPointer]));
// I would do:
ko.mapping.fromJS(states[statesPointer], myViewModel);
Looks like your myViewModel
has own context, so you have to modify my code to get correct ref to the model.
Upvotes: 2