【问题标题】:TempusDominus Knockout Binding Doesn't Fire update Event After InitializingTempusDominus 淘汰赛绑定在初始化后不会触发更新事件
【发布时间】:2019-06-02 21:26:36
【问题描述】:

我正在尝试将 knockoutjs 与 tempusdominus datetimepicker 一起使用,但自定义绑定存在问题。绑定将在初始化期间工作,但通过 datepicker ui 进行的更改或不导致自定义绑定处理更新事件。请忽略缺少的图标,我认为这不是导致问题的原因。

ko.bindingHandlers.datepicker = {
  init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
    //initialize datepicker with some optional options
    var options = allBindings().datepickerOptions || {
      format: 'MM/DD/YYYY HH:mm',
      defaultDate: valueAccessor()()
    };
    $(element).datetimepicker(options);

    //when a user changes the date, update the view model
    ko.utils.registerEventHandler(element, "change.datetimepicker", function(event) {
      var value = valueAccessor();
      if (ko.isObservable(value)) {
        value(event.date);
      }
      console.log("change.datetimepicker"); //, event.date.format());
    });
  },
  update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
    var val = ko.utils.unwrapObservable(valueAccessor());
    if ($(element).datetimepicker) {
      $(element).datetimepicker("date", val);
    }
    console.log("update called"); //, $(element).datetimepicker("date").format());
  }
};

var viewModel = {};

function QuoteViewModel(data) {
  var self = this;
  self.dt2 = ko.observable(moment());
};

viewModel = new QuoteViewModel();
ko.applyBindings(viewModel);

/*
$("#datetimepicker1").on("change.datetimepicker", function (e) {
  console.log("on change", e.date.format());
});
*/
<link href="https://cdn.rawgit.com/Eonasdan/bootstrap-datetimepicker/d004434a5ff76e7b97c8b07c01f34ca69e635d97/build/css/bootstrap-datetimepicker.css" rel="stylesheet"/>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.0/jquery.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/moment.js/2.9.0/moment-with-locales.js"></script>
<script src="https://cdn.rawgit.com/Eonasdan/bootstrap-datetimepicker/d004434a5ff76e7b97c8b07c01f34ca69e635d97/src/js/bootstrap-datetimepicker.js"></script>

<div class="col-sm-6">
  <div class="form-group">
    <div class="input-group date" id="datetimepicker1" data-target-input="nearest">
      <input type="text" class="form-control datetimepicker-input" data-target="#datetimepicker1" data-bind="datepicker: dt2" />
      <div class="input-group-append" data-target="#datetimepicker1" data-toggle="datetimepicker">
        <div class="input-group-text"><i class="fa fa-calendar"></i></div>
      </div>
    </div>
  </div>
</div>
<pre data-bind="text: ko.toJSON($data, null, 2)"></pre> SCRIPT

https://jsfiddle.net/mh_surge/7yrze0Lv/6/

如果我取消注释底部添加非 ko 更改事件处理程序的代码,它总是按预期触发。这让我相信 ko.utils.registerEventHandler 可能存在问题,但该函数的源代码似乎很好。

为什么更新和更改事件在初始化期间只触发一次,我该如何解决?

【问题讨论】:

    标签: knockout.js tempus-dominus-datetimepicker


    【解决方案1】:

    触发的更改事件不包含event.date 属性。您注释掉 jQuery 版本的原因是它针对不同的元素。

    在淘汰赛代码中,您使用的是传递给initupdateelement 参数。这指的是具有datepicker 数据绑定的元素。

    在 jQuery 代码中,您的目标是 $("#datetimepicker1"),这是一个 &lt;div&gt;,它具有由插件实现的自定义 change 元素。

    要解决此问题,您需要:

    • datepicker绑定放在ID为datetimepicker1的元素上(即not放在input元素上)
    • init 函数中使用$(element).on("change.datepicker", ...) 语法
    • 添加 element disposal callback 以清理小部件实例,以防敲除从 DOM 中删除元素

    【讨论】:

      【解决方案2】:

      以下编辑适用于日历弹出窗口和手动编辑文本输入。

      ko.bindingHandlers.dateTimePicker = {
          init: function (element, valueAccessor, allBindingsAccessor) {
              var options = allBindingsAccessor().dateTimePickerOptions || {};
              var initialValue = ko.utils.unwrapObservable(valueAccessor());
              if (initialValue) {
                  options.date = initialValue;
              }
              $(element).datetimepicker(options);
      
              ko.utils.registerEventHandler(element, "change.datetimepicker", function (event) {
                  var value = valueAccessor();
                  if (ko.isObservable(value)) {
                      value(event.date || event.target.value || null);
                  }
              });
      
              ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
                  $(element).datetimepicker("destroy");
              });
          },
          update: function (element, valueAccessor) {
              var val = ko.utils.unwrapObservable(valueAccessor());
              console.log(arguments, val);
              if ($(element).datetimepicker) {
                  $(element).datetimepicker("date", val);
              }
          }
      };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-05-07
        • 2017-01-27
        • 2013-09-10
        • 2022-10-17
        • 1970-01-01
        • 2014-10-30
        • 1970-01-01
        • 2016-08-13
        相关资源
        最近更新 更多