Как настроить локализацию номера для проверки нокаута?

#javascript #knockout.js #knockout-validation

#javascript #knockout.js #проверка нокаута

Вопрос:

Я работаю над веб-приложением с knockout.js и проверка нокаута.

У меня есть одна модель представления, подобная этой:

 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. Вы проверили документацию по локализации для проверки нокаута? github.com/Knockout-Contrib/Knockout-Validation/wiki /…

2. Привет, Стив, я прочитал документацию, но в ней говорится о «отображении сообщений проверки на нескольких языках»…

3. Можете ли вы поделиться кодом number расширения? Это не по умолчанию из knockout.js , так ли это?

4. Привет, расширение номера является частью расширения проверки нокаута, если это возможно, я бы не стал менять код расширения проверки нокаута.

Ответ №1:

Вот исходный код number расширителя, который вы используете:

 // 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 amp;amp; /^-?(?: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 resu<
};

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" />  

Комментарии:

1. Привет, проблема в том, что в итальянском числовом формате десятичные числа делятся на запятую, а не на точку, поэтому я не могу удалить запятую. Основываясь на вашем ответе, возможным решением может быть изменение регулярного выражения.

2. Проверка нокаута позволяет реализовать пользовательские правила. Таким образом, вам не придется перезаписывать number правило для реализации собственной адаптации: github.com/Knockout-Contrib/Knockout-Validation/wiki /…