【问题标题】:jQuery datepicker - Knockout binding set initial datejQuery datepicker - 敲除绑定设置初始日期
【发布时间】:2017-01-12 22:46:23
【问题描述】:

我将 jQuery datepicker 与我制作的自定义绑定一起使用(在结合了来自各地的几个示例之后)。要清楚;更改日期时一切正常,我的问题在于用户不更改日期的情况。这意味着日期选择器值应该是输入日期选择器和文本框元素的初始日期。

这是 MVC,所以我使用的是常规 C# DateTime 对象。请注意,此 DateTime 可以为空,因此是 DateTime? 对象。

以这个场景为例:

用户加载网页,我的 MVC 模型被发送到该网页。我的模型看起来像这样(JSON 格式):

{
    "User": "Christian Haase",
    "Username": "ChristianH",
    "Date": "/Date({som-random-millisecond-number})/"
}

注意: 这不是复制粘贴的,所以有些东西可能看起来有点滑稽,比如 Date 值。

让我们制作一个简单的网页供用户更改此值:

<p data-bind="text: User" ></p>
<input data-bind="value: Username" />
<input data-bind="datepicker: Date, datepickerOptions: { dateFormat: 'dd/mm/yy' }" />

非常简单,但是从标记方面来说这应该足够了。让我们把淘汰赛和日期选择器绑定联系起来。

<script type="text/javascript">
    $(document).ready(function(){

        // Loading the viemodel from MVC (the JSON object)
        var vm = ko.mapping.fromJSON('@Model');

        // Adding the datepicker binding!
        ko.bindingHandlers.datepicker = {
            init: function (element, valueAccessor, allBindingsAccessor) {
                // Getting the datepickerOptions value applied to the binding, if any. Else just an empty object.
                var options = allBindingsAccessor().datepickerOptions || {};

                // Instantiating the datepicker with the options object
                $(element).datepicker(options);

                // Listen for any changes in the element
                ko.utils.registerEventHandler(element, "change", function(){
                    var observable = valueAccessor();
                    var value = $(element).val();

                    // Check to see whether the element.val() is empty or not
                    if(!value){
                        // If empty, I want the observable to hold value 'null'
                        observable(null);
                    } else{
                        // Converting the string '01/09/2016' to an actual JS Date object and settings the observable to that value
                        var date = convertStringToDate(value);
                        observable(date);
                    }
                });
            },
            update: function(element, valueAccessor){
                // Get the value from the viewmodel
                var value = ko.unwrap(valueAccessor());
                // Get the observable
                var observable = valueAccessor();

                // Check whether the value is null or not
                if(value === null){
                    // If the value is null, set the value of the element equal to an empty string
                    $(element).val('');
                }
                else{
                    // If the value is not null (is it something) set the new date on the datepicker.

                    // Parse the JSON date string ('/Date({some-random-millisecond})')
                    var date = parsejsonDateString(value);

                    // Set the new JS Date object to the datepickers 'setDate' function
                    $(element).datepicker('setDate', value);
                }
            }
        }

        vm.save = function(){
            // Function to save the changes made to the object
            // Loggign the date to see the value that'll be sent to the MVC controller
            console.log(vm.Date());
            ....
            // The ajax request is irrelevant
        }

        ko.applyBindings(vm);
    });
</script>

现在,您可能会注意到我正在执行一些调用来操作 Date 对象、JSON 日期字符串 ('/Date({some-random-millisecond})/') 和原始字符串中的日期 ('01/09/2016'),我怀疑其中之一可能会弄乱日期。以下是这些功能:

var jsonDateRE = /^\/Date\((-?\d+)(\+|-)?(\d+)?\)\/$/;
var parseJsonDateString = function (value) {
    var arr = value && jsonDateRE.exec(value);
    if (arr) {
        return new Date(parseInt(arr[1]));
    }
    return value;
};

var convertStringToDate = function (stringDate) {
    if (stringDate != null || stringdate || string != "") {
        var from = stringDate.split("/");
        return new Date(from[2], from[1] - 1, from[0]);
    }
    return "";
}

我对日期选择器初始化时实际发生的事情感到很迷茫,但是如果用户在不更改初始日期的情况下点击“保存”,我的控制台会说; '失效日期'。另一方面,如果用户确实从日期选择器中更改了日期,那么一切都会按预期进行。

我不确定如何真正使这个日期选择器绑定工作,非常感谢所有可能的指导!

如果您需要进一步的解释或代码,请告诉我(尽管我真的没有看到除此之外的其他相关代码)。我很乐意申请所有需要的信息。

【问题讨论】:

  • 查看Date 用户更改前后的值。如果格式不同,您首先要使其匹配“之后”格式。
  • @RoyJ 我不确定我是否理解。能详细点吗?

标签: javascript c# jquery knockout.js datepicker


【解决方案1】:

我整理了一个小例子。请注意,我添加了一个显示Date 值的跨度。这是一种简单的方法来查看它在启动时是什么,以及当您选择不同的值时它会变成什么。在此示例中,似乎没有任何与日期无关的内容,但您的系统中可能有不同的条件。

另请注意,我将parsejsonDateString 的大写更正为parseJsonDateString。如果您的代码中是这样,那将是一个问题(但您应该会在控制台中看到错误)。

var jsonDateRE = /^\/Date\((-?\d+)(\+|-)?(\d+)?\)\/$/;
var parseJsonDateString = function (value) {
    var arr = value && jsonDateRE.exec(value);
    if (arr) {
        return new Date(parseInt(arr[1]));
    }
    return value;
};

var convertStringToDate = function (stringDate) {
    if (stringDate != null || stringdate || string != "") {
        var from = stringDate.split("/");
        return new Date(from[2], from[1] - 1, from[0]);
    }
    return "";
};

ko.bindingHandlers.datepicker = {
  init: function(element, valueAccessor, allBindingsAccessor) {
    // Getting the datepickerOptions value applied to the binding, if any. Else just an empty object.
    var options = allBindingsAccessor().datepickerOptions || {};

    // Instantiating the datepicker with the options object
    $(element).datepicker(options);

    // Listen for any changes in the element
    ko.utils.registerEventHandler(element, "change", function() {
      var observable = valueAccessor();
      var value = $(element).val();

      // Check to see whether the element.val() is empty or not
      if (!value) {
        // If empty, I want the observable to hold value 'null'
        observable(null);
      } else {
        // Converting the string '01/09/2016' to an actual JS Date object and settings the observable to that value
        var date = convertStringToDate(value);
        observable(date);
      }
    });
  },
  update: function(element, valueAccessor) {
    // Get the value from the viewmodel
    var value = ko.unwrap(valueAccessor());
    // Get the observable
    var observable = valueAccessor();

    // Check whether the value is null or not
    if (value === null) {
      // If the value is null, set the value of the element equal to an empty string
      $(element).val('');
    } else {
      // If the value is not null (is it something) set the new date on the datepicker.

      // Parse the JSON date string ('/Date({some-random-millisecond})')
      var date = parseJsonDateString(value);

      // Set the new JS Date object to the datepickers 'setDate' function
      $(element).datepicker('setDate', value);
    }
  }
}


ko.applyBindings({
  User: ko.observable('1'),
  Username: ko.observable('The guy'),
  Date: ko.observable('?')
});
<link href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.6.4/css/bootstrap-datepicker.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.6.4/js/bootstrap-datepicker.min.js"></script>
<p data-bind="text: User" ></p>
<input data-bind="value: Username" />
<input data-bind="datepicker: Date, datepickerOptions: { dateFormat: 'dd/mm/yy' }" />
<div>Date as text: <span data-bind="text:Date"></span></div>

【讨论】:

  • 很抱歉,我看不出bindingHandler 有什么不同。正如您所提到的,唯一的区别是parseJsonDateString(),以及您在跨度中显示日期的事实。我应该从这个答案中理解什么?
  • @Detilium 这是试图复制您的问题。如果我不能复制问题,我就无法解决它。您的初始 Date 值可能有问题。如果您在代码中添加“日期为文本”位,它会显示什么?
  • 感谢您的帮助,但我发现了我的问题。在将数据发送到我的 MVC 控制器之前,我弄乱了我的 observable,因此更改了日期并将 observable 更改为无效的东西。
猜你喜欢
  • 1970-01-01
  • 2017-11-05
  • 2021-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-11
  • 2011-08-13
相关资源
最近更新 更多