Нокаут.двусторонняя привязка js: число в формате строки


У меня есть куча сумм в моей модели представления, которые наблюдаемы, и я хочу, чтобы они хранились как числа, потому что они используются в нескольких вычислениях. Однако, когда я привязываю их к текстовым полям в моем представлении, я хочу, чтобы они отображались в виде специально отформатированной строки (1234.5678 => "1,234.57"). Как лучше всего выполнить двустороннюю привязку в этой ситуации, поскольку я не могу просто использовать привязку значения с моим наблюдаемым?

Пользователь должен иметь возможность ввести "1,234. 56" или "1234.56" в поле textbox, который будет хранить числовое значение 1234.56 в observable, и если я изменю числовое значение (3450) с помощью javascript, значение textbox должно быть обновлено до нового значения, но отформатировано как строка ("3,450").

Я ценю вашу помощь!

2 2

2 ответа:

Я бы реализовал что-то вроде следующего:

JavaScript:

function ViewModel() {
    var self = this;
    self.dollarAmount = ko.observable();

    self.formattedDollarAmount = ko.computed({
        read: function() {
            return applyFormat(self.dollarAmount()); // pseudocode
        },
        write: function(value) {
            var parsedDollarAmount = parseFloat(value);
            if(!isNaN(parsedDollarAmount)) {
                self.dollarAmount(parsedDollarAmount);
            }
            else {
                // recommend adding validation of some sort 
                // so getting here is less likely
                alert("invalid dollar amount"); 
            }
        },
        owner: self
    });
}

HTML:

<input type="text" data-bind="value: formattedDollarAmount" />

Смотрите документацию по вычисляемым наблюдаемым для получения дополнительной информации: http://knockoutjs.com/documentation/computedObservables.html

См.:

Http://jsfiddle.net/Ty8PG/14/

ko.bindingHandlers.numericValue = {
init : function(element, valueAccessor, allBindingsAccessor) {
    var underlyingObservable = valueAccessor();
    var interceptor = ko.computed({
        read: underlyingObservable,
        write: function(value) {

                underlyingObservable(rawNumber(value));

        } 
    });
    ko.bindingHandlers.value.init(element, function() { return interceptor }, allBindingsAccessor);
},   
update : function(element, valueAccessor, allBindingsAccessor) {
element.value = number_format(valueAccessor()(), 2);

}

};

Оригинальное сообщение:

Https://groups.google.com/forum/#! topic/knockoutjs/gvhJt4iSOLk