我有一个名为valueNumber
的Knockout绑定处理程序,它在Globalize的帮助下解析并显示数字:
ko.bindingHandlers.valueNumber = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
// This will be called when the binding is first applied to an element
// Set up any initial state, event handlers, etc. here
var observable = valueAccessor(),
properties = allBindingsAccessor();
var interceptor = ko.computed({
read: function () {
var format = properties.numberFormat || "n2",
formattedNumber = Globalize.format(ko.utils.unwrapObservable(observable), format);
return formattedNumber;
},
write: function (newValue) {
var currentValue = ko.utils.unwrapObservable(observable),
numberValue = Globalize.parseFloat(newValue);
if (!isNaN(numberValue)) {
if (numberValue !== currentValue) {
// The value has changed so update the observable
observable(numberValue);
}
} else if (newValue.length === 0) {
if (properties.isNullable) {
// If newValue is a blank string and the isNullable property has been set then nullify the observable
observable(null);
} else {
// If newValue is a blank string and the isNullable property has not been set then set the observable to 0
observable(0);
}
}
}
});
if (element.tagName.toLowerCase() === 'input') {
ko.applyBindingsToNode(element, { value: interceptor });
} else {
ko.applyBindingsToNode(element, { text: interceptor });
}
}
};
使用它非常简单:
<input data-bind="valueNumber: Cost, numberFormat: 'n1', isNullable: true" type="text" value="" />
当输入文本框失去焦点时,将根据numberFormat属性显示该值。因此,如果用户在上面的文本框中输入了“1.123”,那么当他们选中时,“1.1”将在输入中显示,但存储在observable中的值将为1.123。
这就是它变得棘手的地方。
当输入元素获得焦点/成为活动元素时,我想向输入元素中的用户显示完整值(1.123)。我有一些想法,依靠hasFocus,我可以做到这一点,但我不太确定“正确”的方法会是什么样子。
我理想地希望在一个绑定处理程序中包装这一切,而不是引入额外标记的需要。
根据Robert Westerlund的回答,我提出了一个JSFiddle,可以很好地演示解决方案。这基本上是Robert的解决方案,但根据内置hasFocus
绑定中使用的约定进行了略微重新设置。
哦,为了完整性,这个解决方案正在使用Globalize 0.1.1。快速浏览一下GitHub仓库后,看起来Globalize的API将在未来某个时候发生变化。
答案 0 :(得分:0)
总是很难说“正确”的方法是什么,但我会给你一个至少一种方法的样本。首先,添加一个observable以跟踪焦点状态。
var elementHasFocus = ko.observable(element === document.activeElement);
接下来,您需要确保在发生onblur
或onfocus
事件时更改该值。
element.onblur = function(){ elementHasFocus(false); };
element.onfocus = function(){ elementHasFocus(true); };
在创建init
计算的observable之前,可以在interceptor
方法中添加以上三行。
最后,更新interceptor
的读取方法,以确保它根据焦点状态确定值。
read: function () {
if (elementHasFocus()) {
return ko.unwrap(observable); // If you use newer versions of knockout, you have a convenient ko.unwrap path to the ko.utils.unwrapObservable method.
}
else {
var format = properties.numberFormat || "n2",
formattedNumber = Globalize.format(ko.utils.unwrapObservable(observable), format);
return formattedNumber;
}
}