淘汰计算和输入验证
Knockout computed and input validation
我对淘汰赛还很陌生,正在努力想办法把我理解的两个部分放在一起。
我需要:
- 相互依赖的项目
- 项目的输入值验证
示例:
- 我有以秒为单位的
startTime
,以秒为单元的duration
,以及根据startTime + duration
计算的stopTime
startTime
无法更改- CCD_ 6和CCD_
stopTime
以HH:MM:SS
格式显示和输入- 如果用户更改
stopTime
,则应计算并自动更新duration
- 如果用户更改
duration
,则应计算并自动更新stopTime
我可以让它们相互更新(假设Sec2HMS
和HMS2Sec
在其他地方定义,并在HH:MM:SS
和秒之间转换):
this.startTime = 120; // Start at 120 seconds
this.duration = ko.observable(0);
// This dependency works by itself.
this.stopTimeFormatted = ko.computed({
read: function () {
return Sec2HMS(this.startTime + parseInt(this.duration()), true);
},
write: function (value) {
var stopTimeSeconds = HMS2Sec(value);
if (!isNaN(stopTimeSeconds)) {
this.duration(stopTimeSeconds - this.startTime);
} else {
this.duration(0);
}
},
owner: this
});
或者,我可以使用extenders
或fn
来验证输入,如敲除文档中所示:
ko.subscribable.fn.HMSValidate = function (errorMessage) {
//add some sub-observables to our observable
var observable = this;
observable.hasError = ko.observable();
observable.errorMessage = ko.observable();
function validate(newValue) {
var isInvalid = isNaN(HMS2Sec(newValue));
observable.hasError(isInvalid ? true : false);
observable.errorMessage(isInvalid ? errorMessage : null);
}
//initial validation
validate(observable());
//validate whenever the value changes
observable.subscribe(validate);
//return the original observable
return observable;
};
this.startTime = 120; // Start at 120 seconds
this.duration = ko.observable(0);
this.stopTimeHMS = ko.observable("00:00:00").HMSValidate("HH:MM:SS please");
但我该如何让他们一起工作呢?如果我把HMSValidate
加到第一个块中计算的值上,它就不起作用了,因为当HMSValidate
的validate
函数得到值时,它已经改变了。
我已经在第一个块中实现了这一点,添加了另一个可观察的值,它可以跟踪传递到计算中的"原始"值,然后添加另一个使用该值来决定是否为错误状态的计算值,但这感觉不太优雅。
有更好的方法吗?
http://jsfiddle.net/cygnl7/njNaS/2/
在解决了一周没有解决方法的问题(代码清理时间!)后,我又回到了这里,这就是我所拥有的。
我最终提出了我在问题结尾提到的想法,但将其封装在fn中。
ko.subscribable.fn.hmsValidate = function (errorMessage) {
var origObservable = this;
var rawValue = ko.observable(origObservable()); // Used for error checking without changing our main observable.
if (!origObservable.hmsFormatValidator) {
// Handy place to store the validator observable
origObservable.hmsFormatValidator = ko.computed({
read: function () {
// Something else could have updated our observable, so keep our rawValue in sync.
rawValue(origObservable());
return origObservable();
},
write: function (newValue) {
rawValue(newValue);
if (newValue != origObservable() && !isNaN(HMS2Sec(newValue))) {
origObservable(newValue);
}
}
});
origObservable.hmsFormatValidator.hasError = ko.computed(function () {
return isNaN(HMS2Sec(rawValue()));
}, this);
origObservable.hmsFormatValidator.errorMessage = ko.computed(function () {
return errorMessage;
}, this);
}
return origObservable.hmsFormatValidator;
};
这样做的目的是创建另一个计算的可观测值,该可观测值充当原始可观测值的前沿/滤波器。对于误差状态,该可观测值具有一些其他子可观测值hasError
和errorMessage
。rawValue
会在输入时跟踪该值,以便我们可以检测它是否是一个好值。这处理了我一半需求的验证。
至于使两个值相互依赖,我问题中的原始代码是有效的。为了验证它,我添加了hmsValidate
,如下所示:
this.stopTimeFormatted = ko.computed({
read: function () {
return Sec2HMS(this.startTime + parseInt(this.duration()), true);
},
write: function (value) {
this.duration(HMS2Sec(value) - this.startTime);
},
owner: this
}).hmsValidate("HH:MM:SS please");
请在此处查看其实际操作:http://jsfiddle.net/cygnl7/tNV5S/1/
值得注意的是,write
内部的验证不再是必要的,因为只有在正确验证的情况下,hmsValidate
才会写入该值。
这对我来说仍然有点不雅,因为我检查了几次isNaN,并且必须跟踪原始值(尤其是在read()中),所以如果有人想出另一种方法来做这件事,我会洗耳恭听。
- Angular2 Javascript 验证 输入数字而不是字符
- 在 Angular2 中构建多部分/表单数据 POST 请求并验证输入类型文件
- 如何通过 JavaScript 验证输入字段中的值
- jQuery 验证输入文本是否仅接受数字、单词或日期
- 如何javascript验证<输入类型=文件多个>如果浏览器不支持多个
- 用于验证输入的JavaScript正则表达式超过0个字符
- 验证输入字段和块字符
- Angularjs iu.mask带有日期的验证输入
- 验证输入,更新<td>属性以匹配验证状态
- 通过点击表单外的按钮,使用required和angularjs验证输入字段
- 基于自身输入变化的角度验证输入
- 使用 javascript 验证输入数组
- 年龄验证输入框 - 计算是否超过 18 岁
- JQuery 验证输入类型文件在服务器端失败
- 如何使用jquery或javascript验证输入框的内容
- JSF 和 RichFaces 用于实时验证输入框
- Javascript/Jquery:使用数字范围验证输入
- 如何在更改时验证输入字段并启用提交按钮
- 编码器点火器未验证输入文本
- 在复选框选择后验证输入类型文本