gpt4 book ai didi

javascript - knockout 计算和输入验证

转载 作者:行者123 更新时间:2023-11-29 14:55:39 31 4
gpt4 key购买 nike

我对 knockout 还很陌生,正在尝试弄清楚如何将我理解的两个部分放在一起。

我需要:

  1. 相互依赖的项目。
  2. 项目的输入值验证。

例子:

  • 我有以秒为单位的 startTime,以秒为单位的 duration,以及根据 startTime + duration 计算的 stopTime
  • startTime 不能更改
  • durationstopTime 绑定(bind)到输入字段
  • stopTimeHH:MM:SS 格式显示和输入
  • 如果用户更改stopTimeduration应该被计算并自动更新
  • 如果用户更改durationstopTime应该被计算并自动更新

我可以让它们相互更新(假设 Sec2HMSHMS2Sec 在别处定义,并在 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
});

或者,我可以使用 extendersfn 来验证输入,如 knockout 文档中所示:

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 添加到第一个 block 中的计算中,它不起作用,因为到时候 HMSValidatevalidate 函数获取值它已经被改变了。

我通过添加另一个跟踪传递给计算的“原始”值的可观察对象,然后添加另一个使用该值来确定它是否为错误状态的计算,使其在第一个 block 中工作,但是感觉不是很优雅。

有没有更好的办法?

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;
};

它所做的是创建另一个计算的可观察对象,作为原始可观察对象的前端/过滤器。该 observable 有一些其他的子 observables,hasErrorerrorMessage,附加到它的错误状态。 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() 中),所以如果有人想出另一种方法来做到这一点,我洗耳恭听。

关于javascript - knockout 计算和输入验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18371670/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com