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 puted observable to intercept writes to our observable
var result = koputed({
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 puted 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:
/
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 puted observable to intercept writes to our observable
var result = ko.puted({
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 puted 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/sajjansarkar/vk4x2/1/
Share Improve this question asked Dec 30, 2013 at 0:46 Sajjan SarkarSajjan Sarkar 4,1986 gold badges41 silver badges54 bronze badges1 Answer
Reset to default 9Because your numeric
extender returns a new puted 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 pletely new puted 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.