【问题标题】:Knockout bindingHandler with Eonasdan datepicker does not fire dp.change event when selecting date选择日期时,带有 Eonasdan datepicker 的 Knockout bindingHandler 不会触发 dp.change 事件
【发布时间】:2021-02-13 02:29:54
【问题描述】:

我正在使用 Knockout(ver 3.4.2)、moment(ver 2.29.1) 和 Eonasdan datepicker (ver 4.17.47) 插件来选择日期。

我的问题是当用户选择一个日期时 dp.change 事件没有被触发。它在打开日期选择器/小部件时触发,即用户单击日历图标。

结果是用户选择的第一个日期被忽略(事件在实际选择日期之前触发)并且只有当用户再次打开日期选择器并且事件触发时才会更新日期。

我一直在使用来自 eonasdans 安装页面的敲除绑定句柄示例: http://eonasdan.github.io/bootstrap-datetimepicker/Installing/

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

        //when a user changes the date, update the view model
        ko.utils.registerEventHandler(element, "dp.change", function (event) {
            var value = valueAccessor();
            if (ko.isObservable(value)) {
                if (event.date != null && !(event.date instanceof Date)) {
                    value(event.date.toDate());
                } else {
                    value(event.date);
                }
            }
        });

        ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
            var picker = $(element).data("DateTimePicker");
            if (picker) {
                picker.destroy();
            }
        });
    },
    update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {

        var picker = $(element).data("DateTimePicker");
        //when the view model is updated, update the widget
        if (picker) {
            var koDate = ko.utils.unwrapObservable(valueAccessor());

            //in case return from server datetime i am get in this form for example /Date(93989393)/ then fomat this
            //koDate = (typeof (koDate) !== 'object') ? new Date(parseFloat(koDate.replace(/[^0-9]/g, ''))) : koDate;

            picker.date(koDate);
        }
    }
};

我的淘汰赛视图是这样的:

var exportLicenserModel = function () {
        var self = this;
        self.Startdatum = ko.observable((new moment()).month(0).date(1));
}

HTML 是:

<div class='input-group js-date'>
  <input type="text" class="form-control" id="licenseStartDate" data-bind="datepicker: Startdatum, datepickerOptions: { locale: 'sv', format: 'YYYY-MM-DD', useCurrent: false }" />
  <span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span>
</div>

【问题讨论】:

    标签: javascript knockout.js eonasdan-datetimepicker


    【解决方案1】:

    似乎工作得很好。我在dp.change 处理程序中添加了console.log 语句,还添加了一个文本绑定来显示Startdatum 的当前值。处理程序被调用并且值被更新。看看下面的sn-p:

    ko.bindingHandlers.datepicker = {
      init: function(element, valueAccessor, allBindingsAccessor) {
        //initialize datepicker with some optional options
        var options = allBindingsAccessor().datepickerOptions || {};
        $(element).datetimepicker(options);
    
        //when a user changes the date, update the view model
        ko.utils.registerEventHandler(element, "dp.change", function(event) {
          var value = valueAccessor();
          if (ko.isObservable(value)) {
            if (event.date != null && !(event.date instanceof Date)) {
              value(event.date.toDate());
            } else {
              value(event.date);
            }
          }
          console.log(`Changed to ${value()}`);
        });
    
        ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
          var picker = $(element).data("DateTimePicker");
          if (picker) {
            picker.destroy();
          }
        });
      },
      update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
    
        var picker = $(element).data("DateTimePicker");
        //when the view model is updated, update the widget
        if (picker) {
          var koDate = ko.utils.unwrapObservable(valueAccessor());
    
          //in case return from server datetime i am get in this form for example /Date(93989393)/ then fomat this
          //koDate = (typeof (koDate) !== 'object') ? new Date(parseFloat(koDate.replace(/[^0-9]/g, ''))) : koDate;
    
          picker.date(koDate);
        }
      }
    };
    
    var exportLicenserModel = function() {
      var self = this;
      self.Startdatum = ko.observable((new moment()).month(0).date(1));
    }
    
    ko.applyBindings(new exportLicenserModel());
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.3/js/bootstrap.min.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.3/css/bootstrap.min.css" rel="stylesheet"/>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.47/css/bootstrap-datetimepicker.min.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.47/js/bootstrap-datetimepicker.min.js"></script>
    
    <div class='input-group js-date' style="position: relative">
      <input type="text" class="form-control" id="licenseStartDate" data-bind="datepicker: Startdatum, datepickerOptions: { locale: 'sv', format: 'YYYY-MM-DD', useCurrent: false }" />
      <span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span>
    </div>
    <p>StartDatum: <strong data-bind="text: Startdatum"></strong></p>

    【讨论】:

    【解决方案2】:

    我找到了 dp.change 事件似乎没有触发的原因。

    项目中有一个旧的和过时的 jQuery 类,它查找标记的日期选择器并激活它们,使它们绑定两次。

    $('.js-date').datetimepicker({ locale: 'sv', format: 'YYYY-MM-DD', useCurrent: false });
    

    删除后,一切都按预期工作。

    【讨论】:

      猜你喜欢
      • 2016-09-13
      • 1970-01-01
      • 1970-01-01
      • 2015-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多