具有淘汰赛的货币格式

时间:2016-11-11 11:14:22

标签: knockout.js

我知道之前已经回答了这里的代码(Knockout JS)

ko.observable.fn.withCurrencyFormat = function (precision) {
    var observable = this;
    observable.formatted = ko.computed({
        read: function (key) {
            return '$' + (+observable()).toFixed(precision);
        },
        write: function (value) {
            value = parseFloat(value.replace(/[^\.\d]/g, ""));
            observable(isNaN(value) ? null : value); // Write to underlying storage 
        }
    });

    return observable;
};

但我该如何处理这些情况?

  1. 用户在文本字段中删除0.00,它应该默认返回 至0.00而不是空白
  2. 用户在文本中键入字母 字段,它也应该默认返回0.00而不是返回NaN

1 个答案:

答案 0 :(得分:1)

在生成输出的read函数中,NaN在此处创建:

+observable() // The + tries to "cast" the observable's value to a number

要摆脱NaN,您必须进行isNaN检查:

var nr = +observable();
if (isNaN(nr)) {
  nr = 0;
}

现在,在转换输入的write方法中,为无效输入返回了null值。将其替换为0,默认为$0.00

observable(isNaN(value) ? 0 : value);

如果你可以确定formatted computed是唯一一个写入底层observable的人,你只需要修复其中一个(即你决定格式化输入到系统或输出它们的值) )。

下面的代码段显示了与输入相关联的这些修补程序。就个人而言,我认为这种行为更适合extender,但我不确定它是否重要。

ko.observable.fn.withCurrencyFormat = function (precision) {
    var observable = this;
    observable.formatted = ko.computed({
        read: function (key) {
          var nr = +observable();
          if (isNaN(nr)) nr = 0;
          
          return '$' + nr.toFixed(precision);
        },
        write: function (value) {
        
            value = parseFloat(value.replace(/[^\.\d]/g, ""));
            observable(isNaN(value) ? 0 : value);
        }
    }).extend({notify: 'always'});

    return observable;
};

var obs = ko.observable(0).extend({notify: 'always'});
var val = obs.withCurrencyFormat(2).formatted;

ko.applyBindings({
  val: val
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<input data-bind="value: val">