Можно ли использовать KnockoutJS с замаскированным вводом? - PullRequest
10 голосов
/ 06 февраля 2012

Я использую этот плагин: https://github.com/plentz/jquery-maskmoney для форматирования моего редактора денег ...

Я пытался использовать KnockoutJS в этом редакторе, но он не работает ... Без этой маски все работает нормально ...

Мой тест кода прост:

<input id="Price" data-bind="value: Price"  type="text"  name="Price"> 

Javascript для ввода маски

$("#Price").maskMoney({ symbol: 'R$ ', showSymbol: true, thousands: '.', decimal: ',', symbolStay: false });

и KnockoutJS

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

            this.PriceFinal= ko.computed(function () {
                return this.Price() 
            }, this);
        };

        ko.applyBindings(new ViewModel()); 

Ответы [ 3 ]

14 голосов
/ 05 июня 2012

Вы также можете зарегистрировать обработчик привязки для MaskMoney с помощью Knockout, например:

$(document).ready(function () {

ko.bindingHandlers.currencyMask = {
    init: function (element, valueAccessor, allBindingsAccessor) {
        var options = allBindingsAccessor().currencyMaskOptions || {};
        $(element).maskMoney(options);

        ko.utils.registerEventHandler(element, 'focusout', function () {
            var observable = valueAccessor();

            var numericVal = parseFloat($(element).val().replace(/[^\.\d]/g, ''));
            numericVal = isNaN(numericVal) ? 0 : numericVal;

            observable(numericVal);
        });

        ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
            $(element).unmaskMoney();
        });
    },

    update: function (element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());

        $(element).val(value);
        $(element).trigger('focus');
    }
};

});

, а затем в качестве привязки:

<input type="text" data-bind="currencyMask: MyModel.TotalCost, currencyMaskOptions: { symbol: '$', showSymbol: true, thousands: ',', precision: 0 }" />

Обратите внимание, что я немного подправил плагин MaskMoney, чтобы использовать input.on('focusout.maskMoney', blurEvent); вместо input.bind('blur.maskMoney',blurEvent);, потому что он не вызывал обновление при потере фокуса при щелчке мышью, только при нажатии табуляции.нашел подход обработчика связывания действительно хорошим для плагинов, таких как этот, datepickers и т. д.

11 голосов
/ 07 февраля 2012

Вы должны использовать записываемую вычисляемую наблюдаемую.

function MyViewModel() {
    this.price = ko.observable(25.99);

    this.formattedPrice = ko.computed({
        read: function () {
            return '$' + this.price().toFixed(2);
        },
        write: function (value) {
            // Strip out unwanted characters, parse as float, then write the raw data back to the underlying "price" observable
            value = parseFloat(value.replace(/[^\.\d]/g, ""));
            this.price(isNaN(value) ? 0 : value); // Write to underlying storage
        },
        owner: this
    });
}

ko.applyBindings(new MyViewModel());
0 голосов
/ 05 июля 2013

Если вы используете jquery.formatcurrency, вы можете сделать:

ko.bindingHandlers.currencyMask = {
    init: function (element, valueAccessor, allBindingsAccessor) {
        var options = allBindingsAccessor().currencyMaskOptions || {};
        $(element).formatCurrency(options);
        $(element).keyup(function () {
            $(element).formatCurrency(options);
        });


        ko.utils.registerEventHandler(element, 'focusout', function () {
            var observable = valueAccessor();
            observable($(element).val());
        });

        ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
            $(element).formatCurrency('destroy');
        });
    },

    update: function (element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());

        $(element).val(value);
        $(element).trigger('focus');
    }
};

<input data-bind="currencyMask: priceVal, currencyMaskOptions: { roundToDecimalPlace: 0 }" />
...