Just finding my way in KO, so please be gentle!
Individually each extender works, but when i chain them, the first one (reset) doesnt fire.
Javascript:
ko.extenders.reset = function (target) {
var initialValue = target();
target.reset = function () {
target(initialValue);
}
return target;
}
ko.extenders.numeric = function (target, precision) {
//create a writeable computed observable to intercept writes to our observable
var result = ko.computed({
read: target, //always return the original observables value
write: function (newValue) {
var current = target(),
roundingMultiplier = Math.pow(10, precision),
newValueAsNum = isNaN(newValue) ? 0 : parseFloat(+newValue),
valueToWrite = Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier;
//only write if it changed
if (valueToWrite !== current) {
target(valueToWrite);
} else {
//if the rounded value is the same, but a different value was written, force a notification for the current field
if (newValue !== current) {
target.notifySubscribers(valueToWrite);
}
}
}
}).extend({
notify: 'always'
});
//initialize with current value to make sure it is rounded appropriately
result(target());
//return the new computed observable
return result;
};
function AppViewModel(first, last) {
this.firstName = ko.observable(first).extend({
reset: true
});
this.lastName = ko.observable(last).extend({
reset: true,
numeric: 0
});
self.resetAll = function () {
for (key in self) {
if (ko.isObservable(self[key]) && typeof self[key].reset == 'function') {
self[key].reset()
}
}
}
}
ko.applyBindings(new AppViewModel());
HTML:
1 extender (works):<input data-bind='value: firstName' /><br>
2 extenders (doesnt work)<input data-bind='value: lastName' /><br>
<input type="button" value="Reset All" data-bind="click:resetAll" id="ResetInvoiceButton" />
Fiddle:
http://jsfiddle.net/sajjansarkar/vk4x2/1/
Because your numeric
extender returns a new computed the order of your extenders does matter.
In your current setup your reset
extender runs first and it adds the reset function to your original observable but then the numeric
runs so it overrides your "reset enhanced" observable with a completely new computed observable.
So you just need to execute your extenders in the correct order:
this.lastName = ko.observable(last)
.extend({ numeric: 0 })
.extend({ reset: true });
Demo JSFiddle.
Note that if you want to have a specific order for your extenders you need to apply them in separate extend
calls otherwise the execution order is not guarantied to be in the order of the properties.
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