knockoutjs数据绑定与jquery-ui datepicker

我正在使用jQuery UIdateselect器。 它后面的HTMLinput字段目前作为dependentObservable连接到KnockoutJS ,但是如果在viewmodel中设置了它的值,则datepicker会丢失其格式。

我应该怎么做,而不是丢失的格式? 我想viewModel不知道它是一个jQuerydateselect器。

你可以编写一个自定义绑定,使用dateselect器API在字段中设置date,并通过正确读取date来设置可观察值的值。

自定义绑定可能如下所示:

ko.bindingHandlers.datepicker = { init: function(element, valueAccessor, allBindingsAccessor) { var options = allBindingsAccessor().datepickerOptions || {}, $el = $(element); //initialize datepicker with some optional options $el.datepicker(options); //handle the field changing 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), current = $el.datepicker("getDate"); if (value - current !== 0) { $el.datepicker("setDate", value); } } }; 

你会像这样使用它:

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

datepickeroptions是可选的,可以包含任何你想传递给datepicker()调用的东西。

此外,这假定您正在使用可观察的date。 绑定必须做更多的工作,如果你想做一个非可观的单向绑定,但这是不可能的。

在这里示例: http : //jsfiddle.net/rniemeyer/NAgNV/

我必须对RP Niemeyer的代码进行轻微的编辑,使用dateFormat选项replace我的代码

 $(element).datepicker("getDate") 

 $(element).val() 

所以date的格式化版本正确的传递了。

我一直在使用RP尼迈耶的代码作为上面的答案,但是因为我一直在使用它,所以我对它做了一些小的修改。 我以为我会在这里发帖。 也许它会帮助别人。 这几乎是一样的,唯一的区别是,如果元素在页面加载时有一个值,那么它将保留它的值。 另外,我为$elem$elem一个variables,这样jQuery将不得不处理$(element)

 ko.bindingHandlers['jqDatePicker'] = { 'init': function(element, valueAccessor, allBindingsAccessor) { /* Initialize datepicker with some optional options */ var options = allBindingsAccessor().jqDatePickerOptions || {}, prop = valueAccessor(), $elem = $(element); prop($elem.val()); $elem.datepicker(options); /* Handle the field changing */ ko.utils.registerEventHandler(element, "change", function () { prop($elem.datepicker("getDate")); }); /* Handle disposal (if KO removes by the template binding) */ ko.utils.domNodeDisposal.addDisposeCallback(element, function() { $elem.datepicker("destroy"); }); }, 'update': function(element, valueAccessor) { var value = ko.utils.unwrapObservable(valueAccessor()), $elem = $(element), current = $elem.datepicker("getDate"); if (value - current !== 0) { $elem.datepicker("setDate", value); } } }; 

当用户从datepicker控件中select一个新date时,上面的dateselect器示例将视图模型中的date格式从WCF格式更改为JavaScriptdate格式。

在我的情况下,我将date传回给WCF服务,它不会接受反序列化的JavaScriptdate,它需要WCF格式的date。 我修改了上面的脚本,以WCF格式将视图模型中的date存储起来,这样它就可以以这种格式发送回服务器。

 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")); // store the date in 'WCF String format" var tempdate=$(element).datepicker("getDate"); var tempdatestr="/Date("+tempdate.getTime()+")/"; observable(tempdatestr); }); //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); } } }; 

这是什么对我的特定情况有效。 我正在运行一个足够新的MVC版本,即默认的date时间序列化器在ISO 8601上呈现(请参阅JSONdate和JSON.NET和ASP.NET Web API的噩梦 )。 我的绑定直接写入dateselect器,而是写入input标签的“值”属性。

另外,值得注意的是,我使用的是date.js

 ko.bindingHandlers.dateValue = { update: function(element, valueAccessor, allBindingsAccessor, viewModel) { var value = valueAccessor(), allBindings = allBindingsAccessor(); var valueUnwrapped = ko.utils.unwrapObservable(value); var pattern = allBindings.datePattern || 'MM/dd/yyyy'; var date = Date.parse(valueUnwrapped) $(element).val(date.toString(pattern)); }, init: function(element, valueAccessor, allBindingsAccessor) { //handle the field changing ko.utils.registerEventHandler(element, "change", function () { var observable = valueAccessor(); var date = Date.parse($(element).val()); observable(date.toString("yyyy-MM-ddThh:mm:ss")); }); } } 

绑定看起来像这样:

 <input class="date" type="text" data-bind="dateValue: SomeViewModelDate" /> 

以及打开dateselect器的JavaScript代码:

 $(document).ready(function () { $('.date').datepicker({ dateFormat: "mm/dd/yy" }); }); 

一种解决方法是将自己的date格式化到dependentObservable函数中。 所以你必须在函数中返回类似于return viewModel.someOtherObservable()东西。 格式化返回值。

如果你包含你的代码,我可以解释更多。

格式化dependentObservable内的date(到mm / dd / yyyy)正是我想知道如何去做的。 如果你能帮忙的话,我会发一些我的代码,Peter Mortensen和/或nEEBz。

  <div data-bind="with: technology"> <div class="titleblock"> <label><b>End of Life Date</b></label> <Input type="text" class="ui-datepicker" id="datepicker" data-bind="value: END_OF_LIFE_DATE"/> </div> </div> 

在ViewModel中 – technologydetail.js:

 var technology = ko.observable(); 

在激活:

 return dataContext.getTechnologyById(currentTechnologyId, technology); 

这会在文本框中显示一个如下所示的date:Wed Jan 29 19:00:00 EST 2014,但是我希望它只显示:01/29/2014。 我正在使用这个datepicker选项 – dateFormat:“mm / dd / yy”,但它对显示的初始值没有影响。

我可以使用时刻对其进行格式化,并且它可以很好地显示当前的数据库值,但是它似乎将绑定重新分解为可观察对象,因为它不再在SAVE上进行更新。

 <Input type="text" class="ui-datepicker" id="datepicker" data-bind="value: moment(END_OF_LIFE_DATE()).format('MM/DD/YYYY')" />