这可能最容易用小提琴http://jsfiddle.net/LkqTU/32190/
来描述我有一个可观察的叫价,它有一个扩展器,因此它可以舍入到两位数,并且不允许非数字。
我有一个可写的计算可观察量,它在它前面加上一个美元符号。
但是如果扩展器返回0.第二次它发生$ 0没有返回到文本框(计算的observable)所以如果我在文本框中键入hello world(计算的observable),价格正确报告0并且格式化的价格显示$ 0但是,如果我清除它并再次输入你好世界。此时价格仍为0美元,但格式化价格文本框显示问候世界(即使格式化价格报告为0美元)。必须在某个地方错过通知吗?
这是代码。
ko.extenders.numeric = function(target, precision) {
//create a writable computed observable to intercept writes to our observable
var result = ko.pureComputed({
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 model() {
var self = this;
this.price = ko.observable('29.01').extend({
numeric: '2'
});
this.formattedPrice = ko.computed({
read: function() {
return '$' + this.price()
},
write: function(value) {
value = parseFloat(value.replace(/[^\.\d]/g, ""));
this.price(isNaN(value) ? 0 : value);
},
owner: this
});
}
var mymodel = new model();
$(document).ready(function() {
ko.applyBindings(mymodel);
});
答案 0 :(得分:1)
对我来说似乎有用的是扩展formattedPrice
计算变量以始终通知并修改write方法以仅传入值而不是检查isNaN;你的扩展器无论如何都会执行此操作并强制为0使得if (newValue !== current)
测试永远不会返回true,因为newValue和current在这种情况下总是为0(NaN!== 0 将通过检查):
this.formattedPrice = ko.computed({
read: function() {
return '$' + this.price()
},
write: function(value) {
value = parseFloat(value.replace(/[^\.\d]/g, ""));
this.price(value); //just pass in nan or the value so the extender can check/notify if newValue !== current
},
owner: this
}).extend({
notify: 'always'
});