对于您的特定场景,处理此问题的一种方法是创建一个能够拦截值并进行验证的自定义绑定。这可以通过在要绑定的自定义绑定中创建一个可写计算来完成。优点是您不必担心映射插件自定义您的对象创建。
它可能看起来像:
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/
另一种方法是使用一个选项来扩展 observables 以创建可写计算。
对于您的方案,它可能如下所示:
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/
我认为这两种选择都适合您的情况。我可能更喜欢第二种选择,这样您就可以在使用普通绑定时添加更多这些。