jQuery datepicker - Knockout绑定设置初始日期

时间:2016-09-05 14:25:04

标签: javascript c# jquery knockout.js datepicker

我正在使用jQuery datepicker和我自己制作的自定义绑定(在结合几个示例之后)。要清楚;更改日期时一切正常,我的问题在于用户不更改日期的情况。这意味着datepicker值应该是输入到datepicker和textbox元素的初始日期。

这是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字符串('/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 "";
}

我对在datepicker初始化时实际发生的事情感到很遗憾,但如果用户点击“保存”而没有更改初始日期,我的控制台会说; '失效日期'。另一方面,如果用户从日期选择器更改日期,则一切都按预期工作。

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

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

1 个答案:

答案 0 :(得分:0)

我把一个小例子放在一起。请注意,我添加了一个显示Date值的范围。这是一种简单的方法,可以在启动时查看它是什么,以及当您选择不同的值时它会变成什么样。在这个例子中,似乎没有任何类似日期的东西,但你的系统可能有不同的条件。

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

&#13;
&#13;
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('?')
});
&#13;
<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>
&#13;
&#13;
&#13;