Knockout没有填充DateTime?当initial为null时

时间:2016-07-06 11:05:12

标签: c# asp.net-mvc datetime knockout.js

我使用knockout将我的视图模型绑定到我的视图中。我的视图模型中的多个属性可以为空,例如DateTime? s。这是一个例子:

public class ViewModel
{
    public int ID { get; set; }
    public string Name { get; set; }
    public DateTime? CreationDate { get; set;}
}

如您所见,属性CreationDate是可以为空的DateTime

我将该属性与自定义日期选择器绑定器绑定:

ko.bindingHandlers.datepicker = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        try {
            var jsonDate = ko.utils.unwrapObservable(valueAccessor());
            var value = parseJsonDateString(jsonDate);
            var strDate = value.getMonth() + 1 + "/"
                            + value.getDate() + "/"
                            + value.getFullYear();
            element.setAttribute('value', strDate);
        }
        catch (exc) {
        }
        $(element).change(function () {
            var value = valueAccessor();
            value(element.getAttribute('value'));
        });
    },
    update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var val = valueAccessor();
        val(element.getAttribute('value'));
    }
};

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;
};

这使我能够在视图中绑定我的属性,如下所示:

<input type="text" data-bind="datepicker: CreationDate" />

问题

这就是问题所在。有时,当进入视图时,此属性已为null。 JSON示例可能如下所示:

{
  "Id": 2004,
  "Name": "Test",
  "CreationDate": null
}

如果是这种情况,我将此值更改为datepicker中的某个随机值,并将ajax POST发送到我的控制器,我可以看到模型CreationDate仍然等于null

因此,如果模型进入视图时DateTime为null,我该如何填充模型属性?

1 个答案:

答案 0 :(得分:1)

自行找到解决方案

我设法通过简单地将绑定更改为以下内容来解决我的问题:

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

        //handle the field changing
        ko.utils.registerEventHandler(element, "change", function () {
            var observable = valueAccessor();
            var value = $(element).val();
            // if the input field is empty, the value is falsy and therefore the observable should be = null
            if(!value){
                observable(null);
            } else {
                var date = new Date(value);
                observable(date);
            }
        });

        //handle disposal (if KO removes by the template binding)
        ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
            $(element).datepicker("destroy");
        });

    },
    //update the control when the view model changes
    update: function (element, valueAccessor) {
        var value = ko.unwrap(valueAccessor());
        //if the value received is null, we should display nothing in the input field
        if (value === null) {
            $(element).val(null);
        } else {
            //we need to manipulate the data to show something user friendly to the user
            var date = parseJsonDateString(value);
            var strDate = date.getMonth() + 1 + "/"
                                        + date.getDate() + "/"
                                        + date.getFullYear();
            $(element).val(strDate);
        }
    }
};

所以基本上如果我在update函数中得到的值,只需设置$(element).val(null)。这样,可以正确处理可空属性。