ノックアウトを使用してビューモデルの数値データをバインドすると、正しく表示されますが、ユーザーが入力タグ値を変更すると、データ型が文字列に変更されます。文字列の送信に関する問題は、サーバーが暗黙的な変換を使用できない数値を予期していることです。
元のプロパティ値のデータ型を維持するようにノックアウトに指示する方法はありますか?
ビューモデル名を入力タグ名に一致させる私のサンプルコード。邪魔にならないノックアウトを使用してバインディングを実行します。これは正常に機能します。
// Bind the first object returned to the first view model object
// FNS is the namespace, VM is the view model
FNS.VM.Items[0] = ko.mapping.fromJS(data.Items[0]);
// For each property found, find the matching input and bind it
$.each(FNS.VM.Items[0], function (indexInArray, valueOfElement) {
var attrName = indexInArray;
var attrValue;
if (typeof valueOfElement == "function")
attrValue = valueOfElement();
else
attrValue = valueOfElement;
var a = $('input[name="' + attrName + '"][type="checkbox"]');
if (a.length)
a.dataBind({ checked: 'VM.Items[0].' + attrName });
var b = $('input[name="' + attrName + '"][type="radio"]');
if (b.length)
b.dataBind({ checked: 'VM.Items[0].' + attrName });
var c = $('input[name="' + attrName + '"][type="text"]');
if (c.length)
c.dataBind({ value: 'VM.Items[0].' + attrName });
});
ko.applyBindings(FNS);
値を数値に保つためのいくつかの異なる手法を使用したスレッドを次に示します。 https://groups.google.com/d/topic/knockoutjs/SPrzcgddoY4/discussion
1つのオプションは、この懸念事項をビューモデルにプッシュし、通常のオブザーバブルの代わりに使用するnumericObservable
を作成することです。次のようになります。
ko.numericObservable = function(initialValue) {
var _actual = ko.observable(initialValue);
var result = ko.dependentObservable({
read: function() {
return _actual();
},
write: function(newValue) {
var parsedValue = parseFloat(newValue);
_actual(isNaN(parsedValue) ? newValue : parsedValue);
}
});
return result;
};
サンプル: http://jsfiddle.net/rniemeyer/RJbdS/
別のオプションは、カスタムバインディングでこれを処理することです。 value
バインディングを使用する代わりに、numericValue
バインディングを定義して代わりに使用できます。次のようになります。
ko.bindingHandlers.numericValue = {
init : function(element, valueAccessor, allBindings, data, context) {
var interceptor = ko.computed({
read: function() {
return ko.unwrap(valueAccessor());
},
write: function(value) {
if (!isNaN(value)) {
valueAccessor()(parseFloat(value));
}
},
disposeWhenNodeIsRemoved: element
});
ko.applyBindingsToNode(element, { value: interceptor }, context);
}
};