带有knockout.js数据绑定的引导数据选取器

7jmck4yq  于 2022-11-10  发布在  其他
关注(0)|答案(5)|浏览(146)

这个问题类似于knockoutjs databind with jquery-ui datepicker,但是我想使用Bootstrap datepickers中的一个,而不是jQueryUI日期选择器。
Bootstrap日期选择器的API与jquery-ui不同,我在使用knockout.js时遇到了一些麻烦。我创建了a jsFiddle to try it out
看起来Bootstrap日期选择器可以更简单地使用,因为它不独立存储日期。但是,我想知道jsFiddle是否是使用Bootstrap日期选择器部件和knockout.js的适当方式。

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) {
    }
};
h22fl7wq

h22fl7wq1#

下面是一个示例,说明如何使用正在使用的日期选择器来完成此操作:

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

它看起来不像有任何销毁功能,所以我删除了这一部分。当用户更改日期时,它处理小部件changeDate事件以更新视图模型。update函数处理视图模型何时更改以更新小部件。
如果你想把这个值绑定到一个不可观察的对象上,那么你需要多写一些代码,如果你需要支持的话,请告诉我。
http://jsfiddle.net/rniemeyer/KLpq7/

y4ekin9u

y4ekin9u2#

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

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)
        }
    }
}};
gstyhher

gstyhher3#

接受的答案对我当前版本的日期选择器不起作用。输入没有用可观察的值初始化。我做了一个更新的绑定,并添加了以下内容:

$(element).datepicker('update', dataSource());

这似乎可以达到目的。
下面是一个更新的小提琴,它使用了最新的日期选择器、Bootstrap、jQuery和Knockout:http://jsfiddle.net/krainey/nxhqerxg/

更新日期:

当用户手动编辑文本字段中的值时,我遇到了一些困难,日期选择器不能很好地处理可观察值。该工具会立即解析日期,并将结果插入输入字段。
例如,如果用户尝试编辑10/07/2014,并使用退格键或删除键删除了一个数字(10/0/2014),结果值将立即被解析并插入到文本输入中。如果该值暂时为10/0/2014,则选取器将把日历移动到09/30/2014,然后将该值插入文本字段。如果我试图编辑月份,而该值在一段时间内是1/7/2014,则选择器将切换到2014年1月7日,并将该值插入文本字段。
你可以在这把小提琴上看到这种行为:
http://jsfiddle.net/krainey/nxhqerxg/10/
我必须用一个特殊的处理程序来更新绑定以检测焦点,并绑定一个一次性的blur事件以使其正确处理手动编辑。

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

原始答案中引用的小提琴已更新,以反映这一点:
http://jsfiddle.net/krainey/nxhqerxg/

h5qlskok

h5qlskok4#

这是我的结局

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

    var options = {
        autoclose: true,
        format: 'yyyy-mm-dd',
    }

    //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)) {
            var myDate = event.date;
            var month = myDate.getMonth() + 1;
            var monthText = month;

            if (month < 10)
                monthText = "0" + month;

            var day1 = parseInt(myDate.getDate());
            var dayText = day1;

            if (day1 < 10)
                dayText = '0' + day1;

            value(myDate.getFullYear() + '-' + monthText + '-' + dayText);
        }
    });
},
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());
        widget.setValue(widget.date);
    }
}};
6ie5vjzr

6ie5vjzr5#

有一个更简单的方法可以让bootstrap-datepicker.js和knockout.js一起工作。通常datepicker输入的初始化是在页面加载期间/之后调用的。但是当knockout.js更新值绑定时,datepicker没有正确地更新为新值,所以当你关注datepicker输入时,它默认为01-Jan-2001。
您所要做的就是在任何knockout.js值绑定按照下面的ViewModel方法更新后销毁并重新初始化datepicker输入,这将设置一个要编辑的Map对象。

self.showEditOrderForm = function (data) {
    ko.mapping.fromJS(data, self.entity);
    self.mode('edit');
    $('#edit-dateordered').datepicker('destroy');
    $('#edit-dateordered').datepicker({
        format: 'dd-M-yyyy',
        title: 'Select Date',
        weekStart: 1,
        todayHighlight: true,
        autoClose: true,
        endDate: '0d'
    });
};

相关问题