2016-11-11 7 views
1

Я знаю, что это был дан ответ раньше, и вот код для него (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

В вашей 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 вычислена является единственным письменным основными наблюдаемым, вам нужно только исправить одну из них (то есть вы решите значения формата на ввод их в систему или вывод их).

В приведенном ниже фрагменте показаны эти исправления, связанные с вводом. Лично я считаю, что это поведение лучше подходит для 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">