【问题标题】:knockout mvvm binding with metro.js datepicker与 metro.js datepicker 的淘汰赛 mvvm 绑定
【发布时间】:2015-11-19 07:29:26
【问题描述】:

我试图用 metro.js 日期选择器和淘汰赛来破解我的方式。到目前为止,我的 datepicker 绑定代码如下所示:

ko.bindingHandlers.datepicker = {
  init: function(el, va, ba, model, ctx) {
    var prop = va();
    $(el).datepicker({
      onSelect: function(txt, date) {
        prop(date);
      }
    });
  },
  update: function(el, va, ba, model, ctx) {
    var prop = va();
    var date = ko.unwrap(prop);

    if(date) {
      applyDate(date);
    }

    function applyDate(dt) {
      var j = $(el);
      var dp = j.data('datepicker');
      var inp = j.find('input');
      var fmt = dp.options.format;
      var sDate = format(fmt, dt);
      // dp._calendar.calendar.dayClick(sDate, dt);
      // inp.value = sDate;
      dp._calendar.calendar('setDate', sDate);
      j.find('input').val(dp._calendar.calendar('getDate')).trigger('change', sDate);
    }

    function format(fmt, dt) {
      fmt = fmt.replace('yyyy', dt.getFullYear());
      fmt = fmt.replace('mm', pad(dt.getMonth() + 1));
      fmt = fmt.replace('dd', pad(dt.getDate()));
      return fmt;
    }

    function pad(n) {
      return parseInt(n) < 10 ? '0' + n: '' + n;
    };
  }
}

问题是当我在date 属性上发布模型更新时,它绑定到日期选择器不会更新。我的意思是,它是第一次这样做,但发布后,它无法更新文本框;日历显示还可以。最终我需要更改applyDate函数中的逻辑...

JSBin:http://jsbin.com/rupaqolexa/1/edit?html,js,output

更新:刚刚出现另一个问题...它在 IE 10+ 中不起作用。日期在 UI 中显示为 NaN...

更新:复制步骤

  1. 输入日期第二个文本框:2013/05/13 并单击更改按钮。观察日期在日期选择器文本框中更新。这按预期工作。 (IE 除外)。
  2. 在文本框中输入另一个日期并单击更改按钮。观察日期选择器文本框中的日期未更新。这里预计日期选择器文本框会更新为最新值。

【问题讨论】:

  • 请尝试用其他词语解释问题。不幸的是,即使使用有效的 jsbin 示例也无法理解该问题。顺便说一句,您应该开始使用 SO 代码 sn-ps:blog.stackoverflow.com/2014/09/…
  • @JotaBe 更新后的复制步骤

标签: javascript knockout.js datepicker ko-custom-binding metro.js


【解决方案1】:

在自定义绑定的update 部分,您需要对绑定元素进行所有更改,其中包括日历小部件和相关的input 元素。

我已经修改了代码,现在它可以工作了。

function ViewModel(date) {
  var model = this;
  model.date = ko.observable(date);
  model.set = function() {
    var val = $('#somedate').val();
    var dt = new Date(val);
    model.date(dt);
  };
}

ko.bindingHandlers.datepicker = {
  init: function(el, va, ba, model, ctx) {
    var prop = va();
    $(el).datepicker({
      onSelect: function(txt, date) {
        prop(date);
      }
    });
  },
  update: function(el, va, ba, model, ctx) {
    var newDate = ko.unwrap(va());

    if(newDate) {
      var $el = $(el);
      var datePicker = $el.data('datepicker');
      var $input = $el.find('input');
      var formattedDate = format(datePicker.options.format, newDate);
      datePicker._calendar.calendar('setDate', formattedDate);
      $input.val(formattedDate);
      //$input.val(dp._calendar.calendar('getDate'))
      //  .trigger('change', sDate);
    }

    function format(fmt, dt) {
      fmt = fmt.replace('yyyy', dt.getFullYear());
      fmt = fmt.replace('mm', pad(dt.getMonth() + 1));
      fmt = fmt.replace('dd', pad(dt.getDate()));
      return fmt;
    }

    function pad(n) {
      return parseInt(n) < 10 ? '0' + n: '' + n;
    }
  }
};

var m = new ViewModel();

$(function(){
  ko.applyBindings(m);
});
<link href="//metroui.org.ua/css/metro.css" rel="stylesheet">
<link href="//metroui.org.ua/css/metro-icons.css" rel="stylesheet">
<link href="//metroui.org.ua/css/metro-responsive.css" rel="stylesheet">
<link href="http://metroui.org.ua/css/metro-schemes.css" rel="stylesheet">

<script src="http://metroui.org.ua/js/jquery-2.1.3.min.js"></script>
<script src="http://metroui.org.ua/js/metro.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-debug.js"></script>

<div>
  <div class="input-control text" data-bind="datepicker: date">
    <input type="text">
    <button class="button"><span class="mif-calendar"></span></button>
  </div>
</div>
<div>
  <label>Date</label>
  <div class="input-control text">
    <input type="text" id="somedate"/>
  </div>
  <input type="button" class="button" value="Change" data-bind="click: set"/>
</div>

<div>
  <code data-bind="text: date"></code>
</div>

不过还是有一点小问题:datepiceker 的日历setdate 会添加新的选定日期,而不是替换选定的日期。请参阅 API 文档自行解决此问题。

【讨论】:

  • IE 出现问题。如果您更改模型中的日期,日历将完全有缺陷。
  • 我认为您应该为该问题创建一个新问题,以便可以单独处理。您不需要更改模型中的日期:使用日历小部件进行更改,它也会失败。尝试隔离问题,检查是否是绑定或小部件的问题。谢谢。
猜你喜欢
  • 2013-10-31
  • 2014-08-01
  • 2016-10-26
  • 2013-02-04
  • 2013-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-06
相关资源
最近更新 更多