wir*_*_in 1 knockout-mapping-plugin knockout-2.0 knockout.js knockout-validation
我正在使用knockout和映射插件来自动创建我的视图模型.我在视图模型中有一堆金额,我绑定到文本框.当用户更改文本框中的金额时,我想要的是确保他们输入的是一个数字,并且它大于0,如果不是,我想用0替换他们输入的内容.这似乎是它应该很简单......使用自定义绑定或订阅功能.
我正在阅读的关于敲门验证的所有内容都涉及扩展器和读/写计算的observable,或者添加另一个插件(例如jquery验证).对于这种情况,它们似乎都有点过分,并且必须为要验证的每个observable显式声明扩展器/计算的observable.我有很多使用映射插件自动创建的金额,所以这似乎不合理.
任何帮助将不胜感激!
对于您的特定方案,处理此问题的一种方法是创建一个能够拦截该值并进行验证的自定义绑定.这可以通过在自定义绑定中创建可编写的可写入来进行绑定来完成.优点是您不必担心自定义对象创建的映射插件.
它可能看起来像:
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
};
Run Code Online (Sandbox Code Playgroud)
以下是一个示例:http://jsfiddle.net/rniemeyer/2TnSM/
另一种方法是使用创建可写计算的选项来扩展observable.
对于您的方案,它可能看起来像:
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;
};
Run Code Online (Sandbox Code Playgroud)
然后你会绑定它,如:
<input type="text" name="age" data-bind="value: age.forcePositive()" />
Run Code Online (Sandbox Code Playgroud)
我在这里实现它的方式,你需要调用作为一个函数,forcePositive()以便初始化可写.这样您就可以在没有任何自定义的情况下使用映射插件,只需在要使用此功能的任何observable上执行此操作.
示例:http://jsfiddle.net/rniemeyer/Dy4MH/
我认为这两种选择都适用于您的场景.我可能赞成第二种选择,以便在使用普通绑定时可以添加更多这些选项.