2016-08-24 9 views
0

私のMVCプロジェクトでは、3つの電卓を持つビューがあり、それぞれの電卓は独自のフォームを持ち、3つすべてのフォームに対して1つのビューモデルを持ち、ビューモデルには複数の計算フィールドとフィールドお互いに依存します。

すべてのフィールドに$記号を追加する方法を探していますが、クライアントに表示してからjavascript/KOコードで削除する必要があります(私はできません計算されたフィールドの$記号付きの計算)。

は、私は次の関数を書いた:

this.formatCurrency = function (value) { 
    if (value && value !== "") { 
     value = value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); 
     return "$" + value; 
    } 
} 

をしかし、私はすべての単一のフィールドからこの関数を呼び出す必要があります:

<span data-bind='text: formatCurrency(improvements())'> 

も計算上の任意の計算の前に$記号を削除します。

どのようにすればいいのですか?私は何を思い付くしませんでした...

「本当の」数値の上に ko.pureComputed層を使用してドキュメントの例があります

答えて

0

@ user3297291の答えのおかげで、私はそれを行う方法のアイデアを得ました。

私は私の数値を処理するために、次のbindingHandlerがあります

ko.bindingHandlers.numValue = { 
init: function (element, valueAccessor) { 
    function numValueHandler() { 
     valueAccessor()(this.value); 
    } 
    $(element).on("input change", numValueHandler) 
       .val(ko.unwrap(valueAccessor())); 
    ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 
     $(element).off("input change", numValueHandler); 
    }); 
}, 
update: function (element, valueAccessor) { 
    element.value =ko.unwrap(valueAccessor()); 
} 
}; 

私は値を取得する場合$記号を削除するには、この行を追加:

parseFloat(("" + this.value).replace(/[^\.\d]/g, "")) 

をそして前に$記号を追加しました表示に戻す:

element.value ='$' + ko.unwrap(valueAccessor()); 

したがって、bindingHandler全体は次のようになります。

ko.bindingHandlers.numValue = { 
init: function (element, valueAccessor) { 
    function numValueHandler() { 
     valueAccessor()(parseFloat(("" + this.value).replace(/[^\.\d]/g, ""))); 
    } 
    $(element).on("input change", numValueHandler) 
       .val(ko.unwrap(valueAccessor())); 
    ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 
     $(element).off("input change", numValueHandler); 
    }); 
}, 
update: function (element, valueAccessor) { 
    element.value ='$' + ko.unwrap(valueAccessor()); 
} 
}; 

そして、呼び出しは以下のとおりです。それぞれのフィールド上と数行のコードでformatCurrency関数をコールすることなく、完璧に働いて

<input type="text" data-bind="numValue: improvements" /> 
<input type="text" data-bind="numValue: improvements2" /> 
//etc.. 

ありがとうございます@ user3297291あなたの助けに!

1

this.price = ko.observable(25.99); 

this.formattedPrice = ko.pureComputed({ 
    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 
}); 

出典:http://knockoutjs.com/documentation/computed-writable.html

これは、あなたはあなたのデータバインドにformattedPriceを使用することができます、あなたはそれに書き込むことができます。 priceは数字のままです。

:あなたは後にしているバインドし、それが唯一の一方通行だ場合、あなたはまた textバインディング拡張 currencyFormatterバインドを作成することができます...しかし

を各数のためのあなたのviewmodelに余分なプロパティが必要になります

var formatCurrency = function(value) { 
 
    value = parseFloat(("" + value).replace(/[^\.\d]/g, "")); 
 
    return "$" + (isNaN(value) ? 0 : value); 
 
} 
 

 
ko.bindingHandlers.currencyText = { 
 
    update: function(element, valueAccessor) { 
 
    var originalValue = ko.unwrap(valueAccessor()); 
 
    var formatValue = formatCurrency.bind(null, originalValue); 
 
    ko.bindingHandlers.text.update.call(null, element, formatValue); 
 
    } 
 
}; 
 

 

 
ko.applyBindings({ 
 
    source: ko.observable(1) 
 
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 

 
<input type="number" step="0.1" data-bind="value: source"> 
 
<h1 data-bind="currencyText: source"></h1>

関連する問題