マスクされた入力でKnockoutJSを使用することは可能ですか?

私はそのプラグインを使用しています: https://github.com/plentz/jquery-maskmoney 私のお金のエディタをフォーマット...

私はそのエディタでKnockoutJSを使用しようとしましたが、うまくいきません...そのマスクがなければすべて正常に動作します...

私のコードテストは簡単です:

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

JavascriptからMaskへの入力

$("#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()); 
10

3 答え

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

input.bind( 'blur.maskMoney'、blurEvent)ではなく input.on( 'focusout.maskMoney'、blurEvent); を使用するためにMaskMoneyプラグインを微調整しました。これはマウスのクリックによるフォーカスの喪失に関するアップデートを起動していないためです。

私はKnockoutを初めて使っており、バインディングハンドラのアプローチがこのプラグインやdatepickersなどのプラグインには本当にうってつけだと思っています。

14
追加された
これはIMOの推奨方法です。私はこのコードを使用して、それは素晴らしい仕事をした。
追加された 著者 BeaverProj,
更新時に $(element).trigger( 'focus'); の代わりに $(element).maskMoney( 'mask'); フォーカスイベントが不必要かつ意図しないフォーカスを引き起こすため
追加された 著者 Yoo Matsuo,

書き込み可能な計算可能なオブザーバブルを使用する必要があります。

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());
11
追加された
マッピングプラグインと組み合わせてこのようなことをしている場合は、このプロパティを$ .noop()のように空のものとして作成し、マップして、上記と同様のロジックを適用し、THEN bind
追加された 著者 Jason,
なぜノックアウトエクステンダーを使用しないのですか?
追加された 著者 Hans Roerdinkholder,

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 }" />
0
追加された