我正在尝试获得以下功能:
我有一个SPA,一旦加载,访问REST API并接收日期+时间值列表。
我的目标是让用户轻松选择日期和时间:
我开始尝试使用Bootstrap datetimepicker V3。我定义了一个ko.bindingHandlers
(网上有很多例子),但问题是当绑定发生并启动日期时间选择器时,可观察的有效日期数组仍为空(稍后加载)。我没有找到更新小部件的方法(我尝试注册数组更改并重新初始化datetimepicker:
$el.datetimepicker('destroy'); // or 'remove'
$el.datetimepicker(options); // after I updated options with the new enabledDates
接下来我想和bootstrap-datepicker一起试试运气。在这里,使用绑定和'beforeShowDay'选项,我管理以获得正确的日期。在init
函数中我有:
if (allBindingsAccessor().enabledDates) {
var enabledDates = allBindingsAccessor().enabledDates;
options["beforeShowDay"] = function (date) {
for (var i = 0; i < enabledDates().length; i++) {
var innerDate = enabledDates()[i];
var datePart = innerDate.dateOnly();
if (datePart.getTime() == date.getTime()) {
return true;
}
}
return false;
}
}
然而,当选择日期时 - 我尝试做同样的逻辑,将整个日期“重新翻译”到确切的日期+时间,但运作不正常(见下面的代码)。
最理想的是,我想在日期上显示一些弹出窗口,以防有多个可用时间。否则,即使是两步选择(选择日期,然后从组合中选择时间)也可以。
我创建了一个js-fiddle,它显示了我设法做的事情example fiddle
我可以使用一些现成的组件吗?有没有人知道如何实施?
以下代码无法正常工作 - 如果我使用setDate()函数,则无法在有界可观察对象中获得任何内容。
ko.bindingHandlers.datepicker = {
init: function (element, valueAccessor, allBindingsAccessor) {
//initialize datetimepicker with some optional options
var options = allBindingsAccessor().datepickerOptions || {},
$el = $(element);
// in case enabledDates attribute exists, add a function to check if date exists
// this is used later to set the exact date+time
var getDateTime = function() {
if (allBindingsAccessor().enabledDates) {
// TODO: make more efficient
var enabledDates = allBindingsAccessor().enabledDates;
for (var i = 0; i < enabledDates().length; i++) {
var td= enabledDates()[i];
var datePart = new Date(td.getFullYear(), td.getMonth(), td.getDate());
if (datePart.getTime() == date.getTime()) {
return innerDate;
}
}
return null;
}
};
if (allBindingsAccessor().enabledDates) {
var enabledDates = allBindingsAccessor().enabledDates;
options["beforeShowDay"] = function (date) {
for (var i = 0; i < enabledDates().length; i++) {
var td = enabledDates()[i];
var datePart = new Date(td.getFullYear(), td.getMonth(), td.getDate());
if (datePart.getTime() == date.getTime()) {
return true;
}
}
return false;
}
}
$el.datepicker(options);
// register to change event and update the value accessor (property) on change
function setDate(date) {
if (!date) {
return date;
}
if (allBindingsAccessor().enabledDates) {
var enabledDates = allBindingsAccessor().enabledDates;
for (var i = 0; i < enabledDates().length; i++) {
var td = enabledDates()[i];
var datePart = new Date(td.getFullYear(), td.getMonth(), td.getDate());
if (datePart.getTime() == date.getTime()) {
return innerDate;
}
}
} else {
return date;
}
};
ko.utils.registerEventHandler(element, "changeDate", function(event) {
var value = valueAccessor();
if (ko.isObservable(value)) {
var actualDate = setDate(event.date);
//console.log(actualDate);
value(actualDate);
}
});
//handle disposal (if KO removes by the template binding)
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
$el.datetimepicker("destroy");
});
},
update: function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor()),
$el = $(element);
var current = $el.data("datepicker").getDate();
//var datePart = new Date(value.getFullYear(), value.getMonth(), value.getDate());
if (value - current !== 0) {
$el.data("datepicker").setDate(value);
}
}
};
答案 0 :(得分:0)
我做了一些&#34;解决方法&#34;其中我将选择的日期和时间分成两个不同的元素。
Here是一个有效的例子。通常,流程定义为:
beforeShowDay
函数处理+在绑定(enabledDates
选项)中传递的可观察数组。selectedDate
)。在模型中,我订阅了observable的更改事件。selectedDate
observable更改时,我找到与所选日期对应的所有日期+时间值,并填充选择的选择器绑定到的可观察数组(avaiabledTimes
)selectedTime
)的时间。在模型中,我订阅了它的更改事件。selectedTime
可观察到的变化时,我&#34;合并&#34;所选日期和所选时间,并设置最终选定日期(finalSelectedDate
)。虽然这种作品,但它不是我想要的100%:
availabledTimes
时,由于selectpicker的行为,默认情况下会选择第一个元素,这不是我想要的,因为每当finalSelectedDate
更改时我会调用一些更新UI的ajax例程 - 这意味着在当前设置中,我可能会收到不需要的更新。 (我认为它可能在绑定中 - 我也会尝试修复它。ko.components.register('MyDateTimePicker', ...)
)