如何在此knockoutjs日期选择器代码中避免循环引用?

时间:2012-04-19 20:34:27

标签: javascript jquery-ui knockout.js

如何使用选择列表中的新值打开日期选择器?由于选择列表正在通过对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 );

感谢。

0 个答案:

没有答案