如何配置淘汰验证的数字本地化?

时间:2016-10-11 08:51:53

标签: javascript knockout.js knockout-validation

我正在使用knockout.jsknockout validation处理网络应用程序。

我有一个这样的视图模型:

var viewModel = {
    prop1 : ko.observable().extend({number:true}),
    prop2 : ko.observable().extend({number:true}),
    prop3 : ko.observable().extend({number:true}),
    save : function () {
        var vmValidatable = ko.validatedObservable(viewModel);
        if (!vmValidatable.isValid())
            return false;
    }
}

在前端,如果我尝试使用小数分隔符逗号而不是点保存一个数字,我的保存函数将返回false。

例如:如果prop1有" 1.2"值得保存功能正常工作,如果prop1有" 1,2"值保存函数返回false。

你能帮我吗?

非常感谢

1 个答案:

答案 0 :(得分:0)

以下是您正在使用的number扩展程序的source

// https://github.com/Knockout-Contrib/Knockout-Validation/blob/master/src/rules.js#L221
ko.validation.rules['number'] = {
  validator: function (value, validate) {
    if (!validate) { return true; }
    return ko.validation.utils.isEmptyVal(value) || 
      (validate && /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value));
  },
  message: 'Please enter a number.'
};

我不是正则表达式专家,但它看起来像“,”只有当它们分开3位数时才支持分隔数字。即:您不能使用逗号标记小数点。

console.log(/^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test("100,000"))
console.log(/^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test("100,000.00"))
console.log(/^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test("1,2"))
console.log(/^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test("1,200"))

如果输入的值经过测试且与模式不匹配,则可以添加另一个扩展程序以删除,个字符。不确定这是不是一个好主意。

var test = function(val) {
  if (!val) return true;

  return /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(val);
};


ko.extenders.removeCommas = function(target, option) {
  var result = ko.pureComputed({
    read: target,
    write: function(newValue) {
      var current = target(),
        valueToWrite = test(newValue) ? newValue : newValue.replace(/,/g,
          ".");

      if (valueToWrite !== current) {
        target(valueToWrite);
      } else {
        if (newValue !== current) {
          target.notifySubscribers(valueToWrite);
        }
      }
    }
  }).extend({
    notify: 'always'
  });

  result(target());
  return result;
};

var ViewModel = function() {
  this.input = ko.observable().extend({
    removeCommas: true
  });
}

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

<input data-bind="textInput: input" />