JSFiddle - React, Tailwind, and code Playground
by nyothecat
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.1/knockout-min.js"></script>
<button data-bind='click: updateValue'>Update</button>
<button data-bind='click: revertValue'>Revert</button>
<p data-bind='text: someValue().version'></p>
JavaScript
ko.extenders.keepHistory = function(target, option) {
target.subscribe(function(newValue) {
if (target.reverting) { target.reverting = false; return; }
if(!target.history) target.history = ko.observableArray();
if(!target.revert) {
target.revert = function () {
console.log(target.history()[target.history().length -3]);
var previousVersion = target.history().length < 2 ? null : target.history()[target.history().length -2];
if (!!previousVersion) {
target.reverting = true;
console.log(previousVersion);
target(previousVersion);
}
}
}
target.history.push(newValue);
console.log(target.history());
});
return target;
};
var vm1 = function (name) {
this.name = name;
this.version = 0;
this.toLogString = function () {
return name;
}
}
var vm = function () {
var self = this;
this.someValue = ko.observable(new vm1("My vm1")).extend({keepHistory: true});
this.updateValue = function () {
var clone = Object.assign({}, self.someValue());
clone.version++;
self.someValue(clone);
}
this.revertValue = function () {
if (typeof self.someValue.revert == 'function')
self.someValue.revert();
}
}
var vmi = new vm();
ko.applyBindings(vmi);