Javascript Knockout.js使用拦截器扩展值绑定
这似乎是一种常用的清除/验证/格式化数据的方法,当绑定到输入字段时,它会创建一个可重用的自定义绑定,该绑定使用计算的可观察值。它基本上扩展了默认值绑定,以包括一个拦截器,该拦截器将在写入/读取之前格式化/清理/验证输入Javascript Knockout.js使用拦截器扩展值绑定,javascript,knockout.js,knockout-2.0,knockout-validation,Javascript,Knockout.js,Knockout 2.0,Knockout Validation,这似乎是一种常用的清除/验证/格式化数据的方法,当绑定到输入字段时,它会创建一个可重用的自定义绑定,该绑定使用计算的可观察值。它基本上扩展了默认值绑定,以包括一个拦截器,该拦截器将在写入/读取之前格式化/清理/验证输入 ko.bindingHandlers.amountValue = { init: function (element, valueAccessor, allBindingsAccessor) { var underlyingObservable = valueAcce
ko.bindingHandlers.amountValue = {
init: function (element, valueAccessor, allBindingsAccessor) {
var underlyingObservable = valueAccessor();
var interceptor = ko.computed({
read: function () {
// this function does get called, but it's return value is not used as the value of the textbox.
// the raw value from the underlyingObservable is still used, no dollar sign added. It seems like
// this read function is completely useless, and isn't used at all
return "$" + underlyingObservable();
},
write: function (newValue) {
var current = underlyingObservable(),
valueToWrite = Math.round(parseFloat(newValue.replace("$", "")) * 100) / 100;
if (valueToWrite !== current) {
// for some reason, if a user enters 20.00000 for example, the value written to the observable
// is 20, but the original value they entered (20.00000) is still shown in the text box.
underlyingObservable(valueToWrite);
} else {
if (newValue !== current.toString())
underlyingObservable.valueHasMutated();
}
}
});
ko.bindingHandlers.value.init(element, function () { return interceptor }, allBindingsAccessor);
},
update: ko.bindingHandlers.value.update
};
JSFIDLE示例:
我错过什么了吗?我在任何地方都见过这种方法,但它似乎并不完全有效。read函数似乎完全没有用处,因为它根本没有被使用过。在write函数中,输入“23.0000”会将写入值更改为23,但文本框值不会更新。问题来自自定义绑定的
更新部分。此部件将基于原始模型值更新字段。因此,init
中附加的事件处理程序将通过可写计算程序发送新值,但字段的更新实际上发生在update
中
一个选项是应用init
函数中的值绑定,并跳过update
函数,如:
ko.bindingHandlers.amountValue = {
init: function (element, valueAccessor, allBindingsAccessor) {
var underlyingObservable = valueAccessor();
var interceptor = ko.computed({
read: function () {
// this function does get called, but it's return value is not used as the value of the textbox.
// the raw value from the underlyingObservable, or the actual value the user entered is used instead, no
// dollar sign added. It seems like this read function is completely useless, and isn't used at all
return "$" + underlyingObservable();
},
write: function (newValue) {
var current = underlyingObservable(),
valueToWrite = Math.round(parseFloat(newValue.replace("$", "")) * 100) / 100;
if (valueToWrite !== current) {
// for some reason, if a user enters 20.00000 for example, the value written to the observable
// is 20, but the original value they entered (20.00000) is still shown in the text box.
underlyingObservable(valueToWrite);
} else {
if (newValue !== current.toString())
underlyingObservable.valueHasMutated();
}
}
});
ko.applyBindingsToNode(element, { value: interceptor });
}
};
更新的小提琴:谢谢,这让人沮丧;)