Dirtiable Observable
Basic dirty flag for observables.
by Areson
HTML
<script src="https://raw.github.com/SteveSanderson/knockout/master/build/output/knockout-latest.debug.js"></script>
<input type="text" data-bind="value: observe"></input>
<button data-bind="click: function(){observe.clean()}">Clean!</button>
The value is <span data-bind="text: observe.dirty()?'dirty':'clean'"></span>
<hr/>
<h3>List Example</h3>
<input data-bind="value: listAdd"></input>
<button data-bind="click: addToList">Add to List</button>
<button data-bind="click: observeArray.clean">Clean!</button>
<button data-bind="click: emptyArray">Remove All</button>
The list is <span data-bind="text: observeArray.dirty()?'dirty':'clean'"></span>
<table data-bind="foreach: observeArray()">
<tr>
<td data-bind="text: $data"></td>
</tr>
</table>
JavaScript
/* A fleshed-out implementation of the dirtiable observables
* based on the the work done by Ryan Niemeyer.
* (http://www.knockmeout.net/2011/05/creating-smart-dirty-flag-in-knockoutjs.html)
*/
ko.extenders.dirtiable = function(target) {
var _dirty = {};
_dirty.isDirty = ko.observable(false);
_dirty.initialState = null;
_dirty.tracker = ko.computed(function() {
if(!_dirty.isDirty())
ko.toJSON(target);
return(_dirty.isDirty());
});
//Track changes to observable
_dirty.tracker.subscribe(function() {
if(!_dirty.isDirty() && _dirty.initialState !== ko.toJSON(target))
_dirty.isDirty(true);
});
//Create the dirty flag on the observable
target.dirty = ko.computed(function() {
return(_dirty.isDirty());
});
//Allow users to reset the dirty flag
target.clean = function() {
_dirty.initialState = ko.toJSON(target);
_dirty.isDirty(false);
}
return target;
}
var viewModel = {
observe: ko.observable(42).extend({
dirtiable: true
}),
observeArray: ko.observableArray().extend({
dirtiable: true
}),
listAdd: ko.observable(),
addToList: function() {
this.observeArray.push(this.listAdd());
this.listAdd(null);
},
emptyArray: function() {
this.observeArray.removeAll();
}
}
ko.applyBindings(viewModel);