特定のシナリオでは、これを処理する1つの方法は、値をインターセプトして検証を実行できるカスタムバインディングを作成することです。これは、バインドするカスタムバインディングで計算された書き込み可能ファイルを作成することで実行できます。利点は、オブジェクト作成をカスタマイズするマッピングプラグインについて心配する必要がないことです。
次のようになります。
ko.bindingHandlers.positiveNumericValue = {
init : function(element, valueAccessor, allBindingsAccessor) {
var underlyingObservable = valueAccessor();
var interceptor = ko.computed({
read: underlyingObservable,
write: function(newValue) {
var current = underlyingObservable(),
valueToWrite = isNaN(newValue) ? 0 : parseFloat(+newValue);
if (valueToWrite < 0) {
valueToWrite = 0;
}
//only write if it changed
if (valueToWrite !== current) {
underlyingObservable(valueToWrite);
} else {
//if the rounded value is the same as it was, but a different value was written, force a notification so the current field is updated to the rounded value
if (newValue !== current) {
underlyingObservable.valueHasMutated();
}
}
}
});
ko.bindingHandlers.value.init(element, function() { return interceptor }, allBindingsAccessor);
},
update : ko.bindingHandlers.value.update
};
サンプルは次のとおりです:http://jsfiddle.net/rniemeyer/2TnSM/
別の方法は、書き込み可能な計算を作成するオプションを使用してオブザーバブルを拡張することです。
シナリオでは、次のようになります。
ko.observable.fn.forcePositive = function() {
var underlyingObservable = this;
if (!this.forcePositiveInterceptor) {
this.forcePositiveInterceptor = ko.computed({
read: this,
write: function(newValue) {
var current = underlyingObservable(),
valueToWrite = isNaN(newValue) ? 0 : parseFloat(+newValue);
if (valueToWrite < 0) {
valueToWrite = 0;
}
//only write if it changed
if (valueToWrite !== current) {
underlyingObservable(valueToWrite);
} else {
//if the rounded value is the same as it was, but a different value was written, force a notification so the current field is updated to the rounded value
if (newValue !== current) {
underlyingObservable.valueHasMutated();
}
}
}
});
}
return this.forcePositiveInterceptor;
};
次に、次のようにバインドします。
<input type="text" name="age" data-bind="value: age.forcePositive()" />
ここで実装した方法では、関数として呼び出す必要があるforcePositive()
ため、書き込み可能オブジェクトが初期化されます。これは、カスタマイズなしでマッピングプラグインを使用し、この機能を使用するオブザーバブルでこれを実行できるようにするためです。
サンプル: http: //jsfiddle.net/rniemeyer/Dy4MH/
どちらの選択でもあなたのシナリオにはうまくいくと思います。通常のバインディングを使用しながらこれらをさらに追加できるように、私はおそらく2番目の選択肢を好みます。