2个国家与knockoutjs圆形数字文本框 [英] 2 states roundable numeric text box with knockoutjs
问题描述
我想要一个带有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 BEHAVIOR
$('。numerictextbox')。focusout(function(){
$(this).attr(data-numericvalue,this。 value); //这行不会更新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。这是我的代码的简化版本,所以我希望它对于我的真实场景中的很多属性都是通用的。
Knockout包含事件
绑定和一个 hasFocus
绑定来处理UI输入。
在下面的例子中,我制作了一个隐藏的 realValue
observable存储未修改的输入。当 showDigits
为false时, displayValue
将此数字限制为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:showDigitstype =number/> gt ;
$ b
编辑:很多额外的代码:以下是如何将计算的逻辑封装在可重用的扩展器中:
ko.extenders.digitInput = function(target,option){var realValue = target,showRealValue = ko.observable(false),displayValue = ko.computed返回showRealValue()?realValue():parseFloat(realValue())。toFixed(2);},写入:realValu这); 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.showRealValuetype =number/>< input data-bind =value:value2,hasFocus:value2 .showRealValuetype =number/>
I want to have an html numeric text box with 2 states, when focused, it has to show all decimal places, and when focus is lost, only show 2 decimals. I've almost achieved it.
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/
But my problem is that when focusout occurs, it doesn't update bound property, viewModel in this case. This is a simplified version of my code, so I want it to be generic for a lot of properties in my real scenario.
You're mixing in too much jQuery :)
Knockout has event
bindings and a hasFocus
binding to deal with UI input.
In the example below I've made a viewmodel that has a hidden realValue
observable which stores the unmodified input. The displayValue
limits this number to a 2 digit number when showDigits
is false.
I've used hasFocus
to track whether we want to show the whole number: it's linked to 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"/>
Edit: After comment that a computed is too much extra code: here's how to wrap the computed logic in a reusable extender:
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"/>
这篇关于2个国家与knockoutjs圆形数字文本框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!