Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jquery ui KnockoutJS未捕获jQuery UI日期选择器更改事件_Jquery Ui_Knockout.js - Fatal编程技术网

Jquery ui KnockoutJS未捕获jQuery UI日期选择器更改事件

Jquery ui KnockoutJS未捕获jQuery UI日期选择器更改事件,jquery-ui,knockout.js,Jquery Ui,Knockout.js,我正在尝试将KnockoutJS与jqueryui一起使用。我有一个带有日期选择器的输入元素。我目前正在运行knockout.debug.1.2.1.js,似乎knockout永远不会捕捉到更改事件。元素如下所示: 我甚至尝试过更改valueUpdate事件类型,但没有效果。Chrome似乎在更改值之前引发了一个focus事件,但IE没有 是否有某种淘汰方法可以“重新绑定所有绑定”?从技术上讲,我只需要在将值发送回服务器之前更改它。这样我就可以适应这种工作环境了 我认为问题出在日期选取者的错

我正在尝试将KnockoutJS与jqueryui一起使用。我有一个带有日期选择器的输入元素。我目前正在运行
knockout.debug.1.2.1.js
,似乎knockout永远不会捕捉到更改事件。元素如下所示:


我甚至尝试过更改
valueUpdate
事件类型,但没有效果。Chrome似乎在更改值之前引发了一个
focus
事件,但IE没有

是否有某种淘汰方法可以“重新绑定所有绑定”?从技术上讲,我只需要在将值发送回服务器之前更改它。这样我就可以适应这种工作环境了

我认为问题出在日期选取者的错误上,但我不知道如何解决这个问题


有什么想法吗?

我认为对于jQuery UI datepicker,最好使用自定义绑定,使用datepicker提供的API对日期对象进行读/写

从我的回答来看,绑定可能如下所示:

你会像这样使用它:

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


JSFIDLE中的示例:

我认为可以更轻松地完成:

因此,在init函数中不需要手动更改处理


但在这种情况下,“myDate”变量将只获得可见值,而不是日期对象。

感谢本文,我发现它非常有用

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

i、 e


或者,您可以在绑定中指定:

更新:

 function (element, valueAccessor) {
    var value = ko.utils.unwrapObservable(valueAccessor()),
        current = $(element).datepicker("getDate");

    if (typeof value === "string") {            
       var dateValue = new Date(value);
       if (dateValue - current !== 0)
           $(element).datepicker("setDate", dateValue);
    }               
}

以下是RP Niemeyer答案的一个版本,它将与此处找到的淘汰验证脚本一起使用:

对更改事件处理程序进行更改,首先将输入的值而不是日期传递给验证脚本,然后仅将日期设置为有效的可观察日期。我还添加了此处讨论的自定义绑定所需的validationCore.init:


我还添加了rpenrose关于更改时模糊的建议,以消除一些令人讨厌的日期选择器场景阻碍事情的发展。

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

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

与RP Niemeyer相同,但更好地支持WCF DateTime、时区和使用DatePicker onSelect JQuery属性

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

            var funcOnSelectdate = function () {
                var observable = valueAccessor();
                var d = $(element).datepicker("getDate");
                var timeInTicks = d.getTime() + (-1 * (d.getTimezoneOffset() * 60 * 1000));

                observable("/Date(" + timeInTicks + ")/");
            }
            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());

            //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);
            }
        }
    };
享受:)


虽然所有这些答案都为我节省了大量工作,但没有一个完全适合我。选择日期后,绑定值不会更新。我只能在使用键盘更改日期值,然后从输入框中单击时更新它。我通过使用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);
            }
        }
    };

我怀疑将可观察($(元素).datepicker(“getDate”);语句,并将其注册到options.onSelect中。根据Ryan的解决方案,myDate返回标准日期字符串,这在我的示例中不是理想的。我使用date.js解析该值,因此它将始终返回您想要的日期格式。看看这个例子


我通过更改包含的脚本文件的顺序解决了此问题:

<script src="@Url.Content("~/Scripts/jquery-ui-1.10.2.custom.js")"></script>
<script src="@Url.Content("~/Scripts/knockout-2.2.1.js")"></script>

我需要反复更新服务器上的数据,但我没有完全完成以下需要共享的工作(我的日期格式/日期(1224043200000)/):

在为输出正确格式化模型后,我添加了一个带有文档的模板:


//内联模板

很少有人要求提供动态日期选择器选项。在我的例子中,我需要一个动态的日期范围——因此第一个输入定义了第二个的最小值,第二个设置了第一个的最大值。我通过扩展RP Niemeyer的处理器解决了这个问题。因此,对于他的原作:

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, "change", 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);
        }
    }
};
我还添加了两个与我要修改的选项相对应的处理程序:

ko.bindingHandlers.minDate = {
    update: function(element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor()),
            current = $(element).datepicker("option", "minDate", value);
    }
};

ko.bindingHandlers.maxDate = {
    update: function(element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor()),
            current = $(element).datepicker("option", "maxDate", value);
    }
};
并在我的模板中这样使用它们:

<input data-bind="datepicker: selectedLowerValue, datepickerOptions: { minDate: minValue()}, maxDate: selectedUpperValue" />       
<input data-bind="datepicker: selectedUpperValue, datepickerOptions: { maxDate: maxValue()}, minDate: selectedLowerValue" />

使用前面答案中提供的自定义绑定并不总是可行的。调用
$(element).datepicker(…)
需要相当长的时间,例如,如果您有几十个甚至数百个元素要调用此方法,则必须“延迟”,即按需执行

例如,可以初始化视图模型,将
输入插入DOM中,但是只有当用户单击相应的日期选择器时,才会初始化它们

因此,以下是我的解决方案:

添加允许将任意数据附加到节点的自定义绑定:

KO.bindingHandlers.boundData = {
  init: function(element, __, allBindings) {
    element.boundData = allBindings.get('boundData');
  }
};
使用绑定来附加用于
输入的可观察值:

<input type='text' class='my-date-input'
       data-bind='textInput: myObservable, boundData: myObservable' />

这样,每当用户使用datepicker更改日期时,相应的淘汰观测值也会更新。

我喜欢的是,您没有像dispose回调那样在这个活页夹中抄近路。一个良好的例子,遵循的道路上击倒JS掌握!那么绑定到一个动态创建的元素的日期选择器呢。。。我的意思是,具有实时处理程序的日期采集器。Phoenix_uy:要让日期采集器处理动态创建的对象,请确保不要设置输入的ID或名称。我正在使用它,它工作得很好,除了一件小事——如果我将minDate或maxDate设置为可观察对象,则如果该可观察对象发生更改,它不会得到更新(例如,如果我有两个日期选择器,其中第一个的最大日期是第二个的值,如果我更新第二个,则它不会更新第一个的最大日期)与此问题相同,看起来事件名称是错误的,ko.utils.registerEventHandler(元素,“changeDate”,函数()-应该是ko.utils.registerEventHandler(元素,“change”,函数()此答案看起来不完整?这是对@RPNiemeyer的答案的注释,还是对其他人的答案的注释?这修复了返回日期值为
<div id="documentsContainer">
    <div data-bind="template: { name: 'document-template', foreach: documents, afterRender: afterRenderLogic }, visible: documents().length > 0"></div>
</div>

//Inline template
<script type="text/html" id="document-template">
  <input data-bind="value: RedemptionExpiration" class="datepicker" />
</script>
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, "change", 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);
        }
    }
};
ko.bindingHandlers.minDate = {
    update: function(element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor()),
            current = $(element).datepicker("option", "minDate", value);
    }
};

ko.bindingHandlers.maxDate = {
    update: function(element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor()),
            current = $(element).datepicker("option", "maxDate", value);
    }
};
<input data-bind="datepicker: selectedLowerValue, datepickerOptions: { minDate: minValue()}, maxDate: selectedUpperValue" />       
<input data-bind="datepicker: selectedUpperValue, datepickerOptions: { maxDate: maxValue()}, minDate: selectedLowerValue" />
KO.bindingHandlers.boundData = {
  init: function(element, __, allBindings) {
    element.boundData = allBindings.get('boundData');
  }
};
<input type='text' class='my-date-input'
       data-bind='textInput: myObservable, boundData: myObservable' />
$('.my-date-input').datepicker({
  onSelect: function(dateText) {
    this.myObservable(dateText);
  }
  //Other options
});