当jQuery Datepicker打开时,敲击更改日期戳 [英] Knockout change while jQuery Datepicker is open breaks Datepicker

查看:121
本文介绍了当jQuery Datepicker打开时,敲击更改日期戳的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经设置了一个 jsFiddle 来演示我的问题。

I've set up a jsFiddle to demonstrate my problem.

我在做什么

我正在使用 Knockout 一个 jQuery Datepicker ,如这个问题

I'm using Knockout with a jQuery Datepicker as shown in this question.

我的模型包含一个 observableArray 其中包含具有日期属性的对象。 Knockout为每个对象呈现一个< input type =text> ,并使用RP Niemeyer的 datepicker binding。

My model contains an observableArray which contains objects with date properties. Knockout renders an <input type="text"> for every object, and binds the value to the date using RP Niemeyer's datepicker binding.

发生了什么问题:

如果用户当淘汰赛的型号发生变化(例如,添加新项目)时,日期戳打开,日期戳停止正常工作。从我可以看出,在datepicker打开时创建的最后一个< input type =text> 成为新的datepicker目标。

If the user has a datepicker open when knockout's model changes (e.g., adding a new item), the datepicker stops working correctly. From what I can tell, the last <input type="text"> created while the datepicker is open becomes the new datepicker target. I need to fix the binding so that this does not happen.

示例HTML

<ul data-bind="foreach: dateBoxes">
    <li>
        <span data-bind="text: index"></span>
        <input type="text" data-bind="datepicker: date"/>
    </li>
</ul>

示例Javascript

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());

        //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 = $(element).datepicker("getDate");

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

var model;
var id = 0;
function DateBox(d) {
    var self = this;
    self.date = ko.observable(d);
    self.index = ko.observable(id++);
}
function Model() {
    var self = this;
    self.dateBoxes = ko.observableArray([]);

    self.changeCount = function() {
        if (self.dateBoxes().length < 2) {
            self.dateBoxes.push(new DateBox(new Date()));
        } else if (self.dateBoxes().length > 1) {
            self.dateBoxes.splice(0,1);
        }
    }
    self.tick = function() {
        self.changeCount();
        setTimeout(function() {
            self.tick();
        }, 5000);
    }
    self.tick();
}
model = new Model();
ko.applyBindings(model);


推荐答案

注意:此答案不完整。然而,由于它对于评论来说太大了,并且可能有帮助(对于解决方案),我已经采取了自由,并将其作为答案。任何可以完成此答案的人都可以通过编辑或旋转成另一个更好的答案来进行。

Note: This answer isn't complete. However, as it's too large for a comment and probably helpful (towards a solution) anyhow I've taken the liberty and posted it as an answer. Anyone that can complete this answer is invited to do so through an edit or by spinning off into another better answer.

似乎在破坏派对的事情(摘自从文档,重点是我的):

The thing that seems to be spoiling the party (taken from the documentation, emphasis mine):


当绑定首次应用于元素时,这将被称为一次,并且每当相关联的可观察更改价值

This will be called once when the binding is first applied to an element, and again whenever the associated observable changes value.

如果我黑客防止更新 $ c> datepicker 第一个更新中的调用datepicker不会再破坏(其他问题确实会出现)。对于 init 我已经在末尾添加了这一行:

If I hackisly prevent the update from doing its datepicker calls in the first update the datepicker won't break anymore (other issues do arise though). For the init I've added this line at the end:

element.isFirstRun = true;

然后更新方法将执行以下操作就在 datepicker 调用之前:

Then the update method will do the following just before the datepicker calls:

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

请参阅这个更新的小提琴,结果如下:


  • 现在更新正确的文本框(一件好事);

  • 初始值现在是更详细的DateTime字符串,并在更新后保持这种方式(有点不好);

希望这将有助于实现更完整的解决方案。

Hopefully this will help towards a more complete solution.

这篇关于当jQuery Datepicker打开时,敲击更改日期戳的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆