jock UI datepicker更改事件未被KnockoutJS捕获

Jos*_*ose 134 jquery-ui knockout.js

我正在尝试将KnockoutJS与jQuery UI一起使用.我有一个带有日期选择器的输入元素.我目前正在运行knockout.debug.1.2.1.js,似乎更改事件永远不会被Knockout捕获.元素看起来像这样:

<input type="text" class="date" data-bind="value: RedemptionExpiration"/>
Run Code Online (Sandbox Code Playgroud)

我甚至尝试改变valueUpdate事件类型但无济于事.Chrome似乎focus在更改值之前导致事件,但IE不会.

是否有一些"重新绑定所有绑定"的Knockout方法?从技术上讲,我只需要在将其发送回服务器之前更改值.所以我可以忍受这种解决方法.

我认为问题是datepicker的错,但我无法弄清楚如何解决这个问题.

有任何想法吗?

RP *_*yer 253

我认为对于jQuery UI datepicker,最好使用一个自定义绑定,它将使用datepicker提供的API读取/写入Date对象.

绑定可能看起来像(从我在这里的答案):

ko.bindingHandlers.datepicker = {
    init: function(element, valueAccessor, allBindingsAccessor) {
        //initialize datepicker with some optional options
        var options = allBindingsAccessor().datepickerOptions || {},
            $el = $(element);

        $el.datepicker(options);

        //handle the field changing by registering datepicker's changeDate event
        ko.utils.registerEventHandler(element, "changeDate", function () {
            var observable = valueAccessor();
            observable($el.datepicker("getDate"));
        });

        //handle disposal (if KO removes by the template binding)
        ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
            $el.datepicker("destroy");
        });

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

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

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

        if (value - current !== 0) {
            $el.datepicker("setDate", value);
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

您会像以下一样使用它:

<input data-bind="datepicker: myDate, datepickerOptions: { minDate: new Date() }" />
Run Code Online (Sandbox Code Playgroud)

jsFiddle中的示例:http://jsfiddle.net/rniemeyer/NAgNV/

  • 我喜欢的是你没有在这个活页夹中偷工减料,就像处理回调一样.在通向KnockoutJS的道路上遵循的一个好例子! (21认同)
  • Phoenix_uy:对于使用动态创建的对象的datepicker,请确保不要设置输入的ID或名称. (6认同)
  • 那个绑定到dinamically创建的元素的datepicker呢...我的意思是,带有实时处理程序的datepicker. (2认同)
  • 看起来事件名称是错误的,ko.utils.registerEventHandler(element,"changeDate",function() - 应该是ko.utils.registerEventHandler(元素,"更改",函数() (2认同)

Bra*_*d M 13

以下是RP Niemeyer的答案版本,该版本将与此处的淘汰验证脚本配合使用:http://github.com/ericmbarnard/Knockout-Validation

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).val());
            if (observable.isValid()) {
                observable($(element).datepicker("getDate"));

                $(element).blur();
            }
        });

        //handle disposal (if KO removes by the template binding)
        ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
            $(element).datepicker("destroy");
        });

        ko.bindingHandlers.validationCore.init(element, valueAccessor, allBindingsAccessor);

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

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

        if (value - current !== 0) {
            $(element).datepicker("setDate", value);
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

对change事件处理程序进行更改以将输入的值而不是日期传递给验证脚本,然后仅将日期设置为observable(如果它是有效的).我还添加了这里讨论的自定义绑定所需的validationCore.init:

http://github.com/ericmbarnard/Knockout-Validation/issues/69

我还添加了rpenrose关于改变模糊的建议,以消除一些令人讨厌的日期拣选方案妨碍事情.

  • 似乎对我不起作用,我得到TypeError:observable.isModified不是knockout.validation.js第313行的函数.这里有一个小例子:http://frikod.se/~capitol/fel/test.html (2认同)

Thi*_*PXP 11

我用过不同的方法.由于knockout.js似乎没有在更改时触发事件,因此我强制datepicker在关闭后调用其输入的change().

$(".date").datepicker({
    onClose: function() {
        $(this).change(); // Forces re-validation
    }
});
Run Code Online (Sandbox Code Playgroud)


bru*_*ert 9

虽然所有这些答案都为我节省了大量的工作,但它们都没有完全适合我.选择日期后,绑定的值不会更新.我只能在使用键盘更改日期值然后单击输入框时更新它.我通过使用syb的代码扩充RP Niemeyer的代码来解决这个问题:

ko.bindingHandlers.datepicker = {
        init: function (element, valueAccessor, allBindingsAccessor) {
            //initialize datepicker with some optional options
            var options = allBindingsAccessor().datepickerOptions || {};

            var funcOnSelectdate = function () {
                var observable = valueAccessor();
                observable($(element).datepicker("getDate"));
            }

            options.onSelect = funcOnSelectdate;

            $(element).datepicker(options);

            //handle the field changing
            ko.utils.registerEventHandler(element, "change", funcOnSelectdate);

            //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());
            if (typeof(value) === "string") { // JSON string from server
                value = value.split("T")[0]; // Removes time
            }

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

            if (value - current !== 0) {
                var parsedDate = $.datepicker.parseDate('yy-mm-dd', value);
                $(element).datepicker("setDate", parsedDate);
            }
        }
    };
Run Code Online (Sandbox Code Playgroud)

我怀疑是否存在observable($(element).datepicker("getDate")); 在自己的函数中声明并使用options.onSelect注册它的伎俩?

  • 太感谢了!我尝试了每一个例子,然后在页面底部找到了这个,它最终有效.我只是在我的一个小调整,以便绑定值保持相同的"服务器友好"格式.在你的funcOnSelectdate函数中使用:observable($.datepicker.formatDate('yy-mm-dd') ,$(element).datepicker('getDate'))); (2认同)

小智 6

感谢这篇文章,我发现它非常有用.

如果您希望DatePicker的行为与JQuery UI默认行为完全相同,我建议在更改事件处理程序中的元素上添加模糊:

    //handle the field changing
    ko.utils.registerEventHandler(element, "change", function () {
        var observable = valueAccessor();
        observable($(element).datepicker("getDate"));

        $(element).blur();

    });
Run Code Online (Sandbox Code Playgroud)