如何使用选择列表中的新值打开日期选择器?由于选择列表正在通过对pick可观察对象的订阅进行更新,因此选择可观察对订阅列表中的更改将导致循环引用。
所以问题是当通过选择选择列表值更改日期时,日期选择器应该以新值打开。
http://jsfiddle.net/mathewvance/BFDLE/
<div style="padding-top:10px">
<select data-bind="options: monthOptions, value: month"></select>
<select data-bind="enable: month, options: dayOptions, value: day"></select>
<select data-bind="options: yearOptions, value: year"></select>
<span><input type="hidden" data-bind="datepicker: pick, datepickerOptions: { showOn: 'button' }" /></span>
</div>
// binding handler by rniemeyer
ko.bindingHandlers.datepicker = {
init: function (element, valueAccessor, allBindingsAccessor) {
//initialize datepicker with some optional options
var options = allBindingsAccessor().datepickerOptions || {};
$(element).datepicker(options);
//handle the field changing
ko.utils.registerEventHandler(element, "change", function () {
var observable = valueAccessor();
observable($(element).datepicker("getDate"));
});
//handle disposal (if KO removes by the template binding)
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
$(element).datepicker("destroy");
});
},
update: function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor()),
current = $(element).datepicker("getDate");
if (value - current !== 0) {
$(element).datepicker("setDate", value);
}
}
};
function daysInMonth(month, year) {
return new Date(year, month, 0).getDate();
}
var TravelDate = function (date) {
var self = this;
var dt = date;
this.day = ko.observable();
this.month = ko.observable(dt.getMonth() + 1);
this.year = ko.observable(dt.getFullYear());
this.pick = ko.observable();
this.month.subscribe(function () {
self.fillDayOptions();
});
this.year.subscribe(function () {
self.fillDayOptions();
});
this.pick.subscribe(function (val) {
var dt = new Date(val);
self.year(dt.getFullYear());
self.month(dt.getMonth() + 1);
self.day(dt.getDate());
});
this.travelDate = ko.computed(function () {
var dt = new Date(this.year(), parseInt(this.month(), 10) - 1, this.day());
if (dt == 'Invalid Date')
return null;
return dt;
}, this);
this.dayOptions = ko.observableArray();
this.monthOptions = ko.observableArray([1,2,3,4,5,6,7,8,9,10,11,12]);
this.yearOptions = ko.observableArray([2012,2013,2014]);
this.fillDayOptions = function () {
if (self.month && self.year) {
self.dayOptions.removeAll();
for (var i = 0; i < daysInMonth(self.month(), self.year()); i++) {
self.dayOptions.push(i + 1);
}
}
};
this.init = function () {
self.fillDayOptions();
self.day(dt.getDate());
};
self.init();
}
var viewModel = new TravelDate(new Date());
ko.applyBindings(viewModel );
感谢。