我想要一个带有2个状态的html数字文本框,当聚焦时,它必须显示所有小数位,并且当焦点丢失时,只显示2个小数。我几乎实现了它。
HTML:
<input data-bind="attr: { 'data-numericvalue': valueToRound}" class="numerictextbox"
type="number"/>
使用Javascript:
var viewModel = {
valueToRound: ko.observable(7.4267),
};
//NUMERIC TEXTBOX BEHAVIOUR
$('.numerictextbox').focusout(function () {
$(this).attr("data-numericvalue", this.value); //this line does not update the viewModel
this.value = parseFloat($(this).attr("data-numericvalue")).toFixed(2);
});
$('.numerictextbox').focusin(function () {
if ($(this).attr("data-numericvalue") !== undefined) this.value = $(this).attr("data-numericvalue");
});
ko.applyBindings(viewModel);
Jsfiddle:https://jsfiddle.net/7zzt3Lbf/64/
但我的问题是,当焦点发生时,它不会更新绑定属性,在这种情况下为viewModel。这是我的代码的简化版本,所以我希望它在我的真实场景中对很多属性都是通用的。
答案 0 :(得分:4)
你混合了太多的jQuery:)
Knockout具有event
绑定和hasFocus
绑定来处理UI输入。
在下面的示例中,我创建了一个viewmodel,它具有隐藏的realValue
observable,用于存储未修改的输入。当displayValue
为false时,showDigits
会将此数字限制为2位数字。
我使用hasFocus
来跟踪我们是否要显示整数:它与showDigits
相关联。
var ViewModel = function() {
this.showDigits = ko.observable(true);
var realValue = ko.observable(6.32324261);
this.displayValue = ko.computed({
read: function() {
return this.showDigits()
? realValue()
: parseFloat(realValue()).toFixed(2);
},
write: realValue
}, this);
};
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<input data-bind="value: displayValue, hasFocus: showDigits" type="number"/>
编辑:在评论计算出的额外代码太多之后:这里是如何将计算逻辑包装在可重用的扩展器中:
ko.extenders.digitInput = function(target, option) {
var realValue = target,
showRealValue = ko.observable(false),
displayValue = ko.computed({
read: function() {
return showRealValue()
? realValue()
: parseFloat(realValue()).toFixed(2);
},
write: realValue
}, this);
displayValue.showRealValue = showRealValue;
return displayValue;
};
var ViewModel = function() {
this.value1 = ko.observable(6.452345).extend({ digitInput: true });
this.value2 = ko.observable(4.145).extend({ digitInput: true });
};
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<input data-bind="value: value1, hasFocus: value1.showRealValue" type="number"/>
<input data-bind="value: value2, hasFocus: value2.showRealValue" type="number"/>