HTML5DatePicker和TimePicker在相同的Knockout可观察值上使用自定义绑定处理程序



我正在使用Knockout和HTML5元素将日期和时间绑定到两个单独的控件。每个绑定都是独立工作的,但我很难让它们更新/显示各自属性部分的相同值(日期显示日期,时间显示当天的时间)

我使用了jQuery中的日期选择器和RP的自定义绑定处理程序,我可以绑定到HTML5时间输入元素,但当你更改时间时,我在正确更新可观察到的日期方面遇到了问题-

http://jsfiddle.net/NAgNV/1263/

问题似乎就在这里-

ko.utils.registerEventHandler(element, "change", function() {
var observable = valueAccessor();
console.log($(element).value);
observable($(element).value);
});

如果我选择数组中的第一个对象(为什么它会返回一个数组?),比如$(element)[0].valueAsDate,它似乎会更新可观察对象,但奇怪的是,它会将日期更改为1970,并且不更新日期选择器。

编辑

所以我一直在生产应用程序中使用它,直到本周末才出现问题——奇怪的是,在周六,每当你在时间选择器中更改任何内容时,它就会开始减少小时数。查看验证示例-

http://jsfiddle.net/NAgNV/1339/

发生了什么变化?准备好迎接这一次。。。

调整后的时间定为1970年1月1日。调整后的日期正确设置为正确的日期。当日期选择器设置为中心标准时间的任何一天时,没有问题。当它是中央夏令时时,它开始发疯。问题是,从一个时区获取时间并将其设置为另一个时区的值会使小时递减。

这也使得无法通过手动键入来设置时间。

赏金时间

我在下面更新了Joseph的答案,并奖励了他,因为他在前面投入了额外的时间

HTML输入类型='time'将只包含时间部分,而不包含日期。因此,在读取更改时,您需要在可观察的现有日期上设置刚好时间部分,而不是将该值作为完整日期。

请注意,valueAsDate会为您提供日期,但它不会根据时区进行调整。例如,假设GMT-5,HTML5输入中的"11:04"一旦转换为日期,可能会转换为"6:04"。

以下是一些代码,这些代码应该可以使这项工作正常进行。我建议实施一些淘汰throttling来提高时间选择器的性能。

//handle the field changing
ko.utils.registerEventHandler(element, "change", function () {
var observable = valueAccessor();
console.log('observable - ', observable());
var tzdstOffset = (observable().getTimezoneOffset() + (moment(observable()).isDST() ? 60 : 0));
var adjustedTime = new Date($(element)[0].valueAsDate.getTime() + (tzdstOffset * 60 * 1000));
var adjustedDate = observable();
adjustedDate.setHours(
adjustedTime.getHours(),
adjustedTime.getMinutes(),
adjustedTime.getSeconds()
);
observable(adjustedDate);
});

更新的Fiddle

重新更新Fiddle

附言:数组来自jQuery选择器。使用jQuery选择DOM元素总是会产生一个包含零个或多个元素的数组。数组中的项是底层DOM元素。

最新更新