Validation 导致触发计算值的自定义验证
为了快速了解我的问题,我制作了一个工作JSFIDLE: 在KnockoutJS中,我制作了一个定制的扩展验证程序来测试输入格式是否为HHMM格式。如果是,则返回新值,如果不是,则将其设置回当前工作的旧值Validation 导致触发计算值的自定义验证,validation,knockout.js,Validation,Knockout.js,为了快速了解我的问题,我制作了一个工作JSFIDLE: 在KnockoutJS中,我制作了一个定制的扩展验证程序来测试输入格式是否为HHMM格式。如果是,则返回新值,如果不是,则将其设置回当前工作的旧值 ko.extenders.acValidTimeHHMM = function (target, options) { var result = ko.computed({ read: target, write: function (newValue) { v
ko.extenders.acValidTimeHHMM = function (target, options) {
var result = ko.computed({
read: target,
write: function (newValue) {
var re = /^([0-9]|0[0-9]|1[0-9]|2[0-3])[0-5][0-9]$/;
if (!re.test(newValue)) {
target.notifySubscribers(target());
//Time not in correct format return old time
return;
}
target(newValue);
}
}).extend({ notify: 'always' });
result(target());
return result;
};
我遇到的问题是,当值更改时,我使用计算出的值更新数据库。但是,当我使用验证器将值重置回其原始值时,也会触发此操作。(基于Ryan Rahlf脏旗技术的方法)
问题显然是行target.notifySubscribers(target());在我的验证器中。但是,如果没有这一行,我无法将该值重置为其旧值,也无法找到其他方法来执行此操作
因此,这仅在值实际更改时触发,而不是验证程序重置它。JSFIDLE准确地演示了我的问题,可以用来制作一个工作版本(希望如此),我知道它当前也会在页面加载时启动
我遇到的问题是,当值更改时,我使用计算出的值更新数据库
我不知道您的所有逻辑,但我认为每次更新淘汰视图模型时更新db不是一个好主意。也许你应该看看。使用此插件,您可以构建相同的自定义验证规则,并仅在表单提交事件中更新db
关于你的问题。。。
我发现的最简单的解决方案是向验证扩展发送一个成功回调函数,就像一个选项一样。
差不多
JS:
HTML:
第一次
第二次
谢谢Max-您的解决方案为我提供了一个很好的解决方案。通过更新数据库,我实际上只是根据输入时间获取信息(这必须是实时的),因此需要在成功更新时调用它。
self.update = ko.computed(function () {
self.timeOne();
self.timeTwo();
alert("Fired");
});
var ViewModel = function() {
var update = function () {
alert("value was successfully changed");
};
var cancel = function () {
alert("validation failed. previous value was returned");
};
var timeOne = ko.observable("1100").
extend({
acValidTimeHHMM: {
success: update,
fail: cancel
}
});
var timeTwo = ko.observable("1248").
extend({ acValidTimeHHMM: { success: update } });
return {
timeOne: timeOne,
timeTwo: timeTwo
};
};
ko.extenders.acValidTimeHHMM = function(target, option) {
var baseOptions = {
success: null,
fail: null
};
$.extend(baseOptions, option);
var result = ko.computed({
read: target,
write: function (newValue) {
var oldValue = target();
if(newValue == oldValue) return;
var re = /^([0-9]|0[0-9]|1[0-9]|2[0-3])[0-5][0-9]$/;
if (!re.test(newValue)) {
target.notifySubscribers(oldValue);
if(typeof(baseOptions.fail) == "function")
baseOptions.fail();
return;
}
target(newValue);
if(typeof(baseOptions.success) == "function")
baseOptions.success()
}
}).extend({ notify: 'always' });
result(target());
return result;
};
ko.applyBindings(new ViewModel());
<p>Time One<input data-bind='value: timeOne' /></p>
<p>Time Two<input data-bind='value: timeTwo' /></p>