I'm trying to create a binding handler which allows me to track if any of the values used in the binding has changed:
<div id="container1" data-bind="dirty: $root.container1Dirty">
<span data-bind="visible: $root.container1Dirty">*</span>
<label>
Text 1
<input data-bind="value: $root.text1" />
</label>
</div>
So far I tried the following:
ko.bindingHandlers.dirty = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var counter = 0;
var dirtyObservable = valueAccessor();
var appliedBindings = false;
var computed = ko.computed(function() {
if (!appliedBindings) {
// I was hoping this would subscribe all the used observables
ko.applyBindingsToDescendants(bindingContext, element);
appliedBindings = true;
}
// make sure subscribe is triggered by returning a new value
return counter++;
});
computed.subscribe(function() {
dirtyObservable(true);
});
return { controlsDescendantBindings: true };
}
};
I was hoping ko.applyBindingsToDescendants
would subscribe the observables used in all the bindings within that container. This however doesn't seem to be the case; see http://jsfiddle.net/F3uMr/1/.
Is there another way to achieve this? Or would it be better to create a ViewModel for each container and then use the dirty flag?
Not sure if this is the best solution, but you can wrap the dirty flag into a 'base class' and keep all of the logic shared between view models there. For example:
Fiddle is here
<input type='text' data-bind="value: textBox, event: { keyup: isDirty }">
<input type='button' value='click me if you can' data-bind="click: save, ,enable: isDirty">
var BaseViewModel = function (saveUrl, data) {
var self;
this.isDirty = ko.observable(false);
this.save = function(){
var jsData = ko.toJS(data);
alert('save: ' + jsData.textBox);
};
};
var pageViewModel = function(){
var self = this;
this.textBox = ko.observable('');
ko.utils.extend(self, new BaseViewModel('url for save', {textBox: self.textBox}));
}
ko.applyBindings(new pageViewModel());
If you don't want to specify events and just apply the 'dirty' check to all of the observables, you can try something like this: Fiddle
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With