与knockout.js数据绑定的Bootstrap datepicker

Bri*_*unt 22 datepicker twitter-bootstrap knockout.js

这个问题类似于knockoutjs databind和jquery-ui datepicker,但是我想使用其中一个Bootstrap datepickers而不是jQueryUI datepicker .

Bootstrap日期选择器的API与jquery-ui不同,我在使用knockout.js工作时遇到了一些麻烦.我创建了一个jsFiddle来试试.

似乎Bootstrap日期选择器可以更简单地使用,因为它不能独立存储日期.但是,我想知道jsFiddle是否是与knockout.js一起使用Bootstrap datepicker小部件的合适方式,即

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

      ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
            $(element).datepicker("destroy");
        });
    },
    update: function(element, valueAccessor) {
    }
};
Run Code Online (Sandbox Code Playgroud)

RP *_*yer 41

以下是如何使用您正在使用的datepicker完成此操作的示例:

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

      //when a user changes the date, update the view model
      ko.utils.registerEventHandler(element, "changeDate", function(event) {
             var value = valueAccessor();
             if (ko.isObservable(value)) {
                 value(event.date);
             }                
      });
    },
    update: function(element, valueAccessor)   {
        var widget = $(element).data("datepicker");
         //when the view model is updated, update the widget
        if (widget) {
            widget.date = ko.utils.unwrapObservable(valueAccessor());
            if (widget.date) {
                widget.setValue();            
            }
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

它看起来没有任何破坏功能,所以我删除了那一块.changeDate当用户更改日期时,这将处理窗口小部件事件以更新视图模型.update更改视图模型以更新窗口小部件时,该函数处理.

如果要将值绑定到不可观察的值,则需要更多代码.如果您需要支持,请告诉我.

http://jsfiddle.net/rniemeyer/KLpq7/

  • 这是一个[jsFiddle](http://jsfiddle.net/bmh_ca/uQcCx/2/),当字段更新时,它具有更适合的字符串 - >日期转换.这仍然需要注意,只有通过小部件的更改才会被注册; 对输入字段进行更改不会更新模型. (2认同)
  • 这是一个绑定`change`事件的更新,以响应对输入字段的更改:http://jsfiddle.net/rniemeyer/uQcCx/3/ (2认同)
  • 我注意到这个例子不再适用于日期选择器的初始日期不是文本框中的日期.这是我试图在我自己的代码中修复的错误.有任何想法吗? (2认同)

Phi*_*p P 6

我目前的版本是已经显示的解决方案之间的混合:

ko.bindingHandlers.datepicker = {
init: function (element, valueAccessor, allBindingsAccessor) {

    var unwrap = ko.utils.unwrapObservable;
    var dataSource = valueAccessor();
    var binding = allBindingsAccessor();

    //initialize datepicker with some optional options
    var options = allBindingsAccessor().datepickerOptions || {};
    $(element).datepicker(options);
    $(element).datepicker('update', dataSource());
    //when a user changes the date, update the view model
    ko.utils.registerEventHandler(element, "changeDate", function (event) {
        var value = valueAccessor();
        if (ko.isObservable(value)) {
            value(event.date);
        }
    });
},
update: function (element, valueAccessor) {
    var widget = $(element).data("datepicker");

    var value = ko.utils.unwrapObservable(valueAccessor());

    //when the view model is updated, update the widget
    if (widget) {
        widget.date = value;
        if (widget.date) {
            widget.setValue();
            $(element).datepicker('update', value)
        }
    }
}};
Run Code Online (Sandbox Code Playgroud)


kip*_*ney 5

使用当前版本的日期选择器,接受的答案对我不起作用.输入未使用observable的值进行初始化.我做了一个更新的绑定,我添加了这个:

$(element).datepicker('update', dataSource());
Run Code Online (Sandbox Code Playgroud)

这似乎可以解决问题.

这是一个更新的小提琴,使用最新的日期选择器,Bootstrap,jQuery和Knockout:http://jsfiddle.net/krainey/nxhqerxg/

更新:

当用户手动编辑文本字段中的值时,我遇到了日期选择器与observable不能很好地匹配的问题.该工具将立即解析日期,并将结果插入输入字段.

例如,如果用户尝试编辑10/07/2014,并使用退格键或删除键删除数字(10/0/2014),则会立即解析结果值并将其插入到文本输入中.如果该值暂时为10/0/2014,则选择器会将日历移至2014年9月30日,并将该值插入文本字段.如果我试图编辑月份,并且价值是,2014年1月7日,选择器将转移到2014年1月7日,并将该值插入文本字段.

你可以在这个小提琴中看到这种行为:

http://jsfiddle.net/krainey/nxhqerxg/10/

我必须使用特殊处理程序更新我的绑定以检测焦点,并绑定一次性模糊事件以使其正确处理手动编辑.

$(element).on("changeDate", function (ev) {
    var observable = valueAccessor();
    if ($(element).is(':focus')) {
        // Don't update while the user is in the field...
        // Instead, handle focus loss
        $(element).one('blur', function(ev){
            var dateVal = $(element).datepicker("getDate");
            observable(dateVal);
        });
    }
    else {
        observable(ev.date);
    }
});
Run Code Online (Sandbox Code Playgroud)

原始答案中引用的小提琴已经更新,以反映这一点:

http://jsfiddle.net/krainey/nxhqerxg/