I currently have two Knockout extension functions. One adds a member to the Observable while the other intercepts the read and write operations.
When combining the extension methods the order of application has an unwanted effect.
Simplified code examples below.
ko.extenders.format = function(target) {
var result = ko.computed(function(){
return "$" + target();
});
target.formatted = result;
return target;
};
ko.extenders.numeric = function(target, precision) {
var result = ko.computed({
read: function() {
var current = parseFloat(target());
return current.toFixed(precision);
},
write: function(newValue) {
newValue = parseFloat(newValue);
target(newValue.toFixed(precision));
}
});
return result;
};
In the numeric method I can check for the formatted member and assign it to the new computed but I don't want to give it knowledge of the other method. This also won't be maintainable if I decide to add more members off the observable or extensions.
if(target.hasOwnProperty("formatted")){
result.formatted = target.formatted;
}
Heres a fiddle without the hasOwnProperty fix. http://jsfiddle.net/gs5JM/2/
Notice that MyValue4 - Format: is blank due to the order of extender application and the loss of the formatted member.
Is there a better pattern to achieve the same end result and make the code more flexible?
The problem is that your format
extender refers to original observable and numeric
creates a new one. So format
and numeric
work with completely different observables. Looks like you should consider to return original observable in both cases.
I would rewrite your numeric
this way:
ko.extenders.numeric = function(target, precision) {
ko.computed(function(){
var current = parseFloat(target());
target(isNaN(current) ? 0 : current.toFixed(precision));
});
return target;
};
Anonymous computed
will create a subscription to target
value changes with immediate evaluation. The evaluation function will try to parse a value and reassign precised numeric value to the target observable.
http://jsfiddle.net/gs5JM/3/
Note: You should not care about possible circular dependency because KO will not re-evaluate computed
while it's already evaluating.
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