datepicker init绑定时出错

时间:2014-11-26 16:38:00

标签: twitter-bootstrap knockout.js datepicker momentjs

我在敲除

上的init事件绑定时遇到问题

这是代码:

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

        element.isFirstRun = true;
    },
    update: function (element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());

        //handle date data coming via json from Microsoft
        if (String(value).indexOf('/Date(') == 0) {
            value = new Date(parseInt(value.replace(/\/Date\((.*?)\)\//gi, "$1")));
        }

        if (element.isFirstRun) {
            $(element).val(value);
            element.IsFirstRun = false;
            return;
        }

        var current = $(element).datepicker("getDate");

        if (value - current !== 0) {
            $(element).datepicker("setDate", value);
        }
    }
};

代码片段在哪里“observable($(element).datepicker(”getDate“));”在文件“moment-datepicker.js:443”中给出错误“Uncaught TypeError:undefined is not function”,此文件的代码行443是摘录:

$.fn.datepicker = function (option, val) {
        var results = [];
        var chain = this.each(function () {
            var $this = $(this),
                data = $this.data('datepicker'),
                options = typeof option === 'object' && option;
            if (typeof option === 'string') {
                if (data) {
                    if (val) {
line 443                        var result = data[option](val); //crashes exactly here
                        if (typeof result !== 'undefined')
                            results.push(result);
                    }
                }
            } else if (!data) {
                $this.data('datepicker', (data = new Datepicker(this, $.extend({}, $.fn.datepicker.defaults, options))));
            }
        });
        return results.length == 1 ? results[0]
            : results.length ? results
            : chain;
    };

1 个答案:

答案 0 :(得分:0)

因为,你正在使用时刻js尝试它的敲除绑定处理程序。

以下是处理程序:

<强>更新 这是我使用的方式...... 没有jquery ui js ,否则 jquery ui datepicker 会与 moment-datepicker

冲突
<script src="jquery-1.7.2.js" type="text/javascript"></script>
<script type="text/javascript" src="moment.js"></script>
<!-- optional -->
<script type="text/javascript" src="moment-range.js"></script>
<script type="text/javascript" src="moment.i18n.all.min.js"></script>
<!-- /optional -->
<script src="knockout-3.0.0.min.js" type="text/javascript"></script>
<script type="text/javascript" src="moment-datepicker.js"></script>
<script type="text/javascript" src="moment-datepicker-ko.js"></script>

(function ($, ko, moment) {

    //#region Utils

    var detectDataType = function (value) {
        for (var fname in detectDataType.typeDetection) {
            var f = detectDataType[fname];
            if (f(value)) {
                return detectDataType.typeDetection[fname];
            }
        }
        return null;
    }

    detectDataType.isString = function (value) {
        return typeof value === 'string';
    };
    detectDataType.isDate = function (value) {
        return typeof value === 'object' && Object.prototype.toString.call(value) === "[object Date]";
    };
    detectDataType.isMoment = function (value) {
        return moment.isMoment(value);
    };
    detectDataType.typeDetection = {
        "isMoment": "moment",
        "isString": "string",
        "isDate": "date"
    };
    
    var elBinder = function($el) {
        return {
            set: function (value) {
                var funcs = elBinder.functions[$el.data(elBinder.DATATYPE_KEY)] || elBinder.functions['_default'];
                var func = funcs['set'] || elBinder.functions['_default']['set'];
                return func($el, value);
            },
            get: function () {
                var funcs = elBinder.functions[$el.data(elBinder.DATATYPE_KEY)] || elBinder.functions['_default'];
                var func = funcs['get'] || elBinder.functions['_default']['get'];
                return func($el);
            },
            register: function (dataType) {
                $el.data(elBinder.DATATYPE_KEY, dataType);
            }                
        }
    }
    
    elBinder.DATATYPE_KEY = "datepicker.ko.dataType";

    elBinder.functions = {
        '_default': {
            get: function ($el) {
                return $el.datepicker('get');
            },
            set: function ($el, value) {
                $el.datepicker('set', value);
            }
        },
        'iso': {
            get: function ($el) {
                var value = $el.datepicker('get');
                return (value && value.format('YYYY-MM-DD'));
            },
            set: function ($el, value) {
                var mnt = moment(value);
                $el.datepicker('set', mnt);
            }
        },
        'format': {
            get: function ($el) {
                return $el.datepicker('getAsText');
            }
        },
        'date': {
            get: function ($el) {
                var value = $el.datepicker('get');
                return (value && value.toDate());
            }
        }
    };

    //#endregion

    ko.bindingHandlers.datepicker = {
        init: function (element, valueAccessor, allBindingsAccessor) {
            var options = allBindingsAccessor().datepickerOptions || {};
            var dataType = options.dataType || detectDataType(ko.utils.unwrapObservable(valueAccessor()));
            dataType = !dataType || dataType == 'string' ? 'iso' : dataType;
            var $el = $(element).datepicker(options);

            elBinder($el).register(dataType);

            ko.utils.registerEventHandler(element, "changeDate", function (event) {
                var accessor = valueAccessor();
                if (ko.isObservable(accessor)) {
                    var value = elBinder($el).get();
                    accessor(value);
                }
            });
        },
        update: function (element, valueAccessor) {
            elBinder($(element))
                .set(ko.utils.unwrapObservable(valueAccessor()));
        }
    };
})(jQuery, this.ko, this.moment);