2个国家与knockoutjs圆形数字文本框 [英] 2 states roundable numeric text box with knockoutjs

查看:91
本文介绍了2个国家与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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆