Knockout N-Level Undo
by gurkavcu
HTML
<script src="https://github.com/downloads/SteveSanderson/knockout/knockout-1.3.0beta.js"></script>
<script src="https://raw.github.com/SteveSanderson/knockout.mapping/master/build/output/knockout.mapping-latest.js"></script>
<div>
<button data-bind="click: function() { undo(); }">Undo</button>
<input data-bind="value: firstName" />
<input data-bind="value: lastName" />
<textarea data-bind="value: text"></textarea>
</div>
JavaScript
(function() {
window.undoStack = [];
var currentState = JSON.stringify({
firstName: 'Paul',
lastName: 'Tyng',
text: 'Text'
})
, performingUndo = false
, viewModel = ko.mapping.fromJSON(currentState);
ko.dependentObservable(function() {
ko.toJS(viewModel); //subscribe to all properties
}, viewModel).subscribe(function() {
if(!performingUndo) {
undoStack.push(currentState);
currentState = ko.mapping.toJSON(viewModel);
}
});
window.undo = function() {
performingUndo = true;
if(undoStack.length > 1)
{
currentState = undoStack.pop();
ko.mapping.fromJSON(currentState, {}, viewModel);
}
else {
currentState = undoStack[0];
ko.mapping.fromJSON(undoStack[0], {}, viewModel);
}
performingUndo = false;
};
ko.applyBindings(viewModel);
})();