我的淘汰赛自定义绑定不是双向绑定

时间:2016-06-08 14:55:01

标签: asp.net knockout.js data-binding

所有

环境:

asp.net 3.5

我的日期通过lib:Newtonsoft.json库

使用ISO8601格式序列化

目标:

在我的模型上的日期字段(Document.DocumentDate)和ajax控件工具包日历扩展器的文本框之间创建双向绑定。 ajax日历在幕后使用文本字段,因此我将下面的绑定应用于文本字段。当页面加载时,从对象到控件的绑定有效但在我使用日历扩展器更改文本字段后,文本值被更改但我的基础对象没有更新,绑定的update()方法也没有被调用。 / p>

以下是代码:

data-bind="date: {jsonDate : Document.DocumentDate }" 

ko.bindingHandlers.date = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var value = valueAccessor();
        var dtStr = ko.unwrap(value.jsonDate);

        var dt = new Date(dtStr);

        var ret = dt.getMonth() + 1 + "/" + dt.getDate() + "/" + dt.getFullYear();
        $(element).val(ret);
    },
    update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
    }
};

注:

如果我将数据绑定表达式更改为:

data-bind="value: Document.DocumentDate"

一切正常但日期不是我想要的文字字段。这就是为什么我使用自定义绑定来格式化文本字段中的日期。

2 个答案:

答案 0 :(得分:0)

您可以使用extenter格式化日期(Knockout.js format date item

或者您可以使用格式化函数将“value”绑定包装为可编辑的大小写:

// Formatted value accessor creator

function createValueAccessor(dateValue) {
  return function() {
    return ko.computed({
  	  read: function() {
       var dtStr = ko.unwrap(dateValue);
       var dt = new Date(dtStr);
       return dt.getMonth() + 1 + "/" + dt.getDate() + "/" + dt.getFullYear();
  	  },
      write: function(newValue) { dateValue(newValue); }
    });
  }
}

// Binding handler

ko.bindingHandlers.dateValue = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var value = valueAccessor();
        ko.bindingHandlers.value.init(element, createValueAccessor(value), allBindingsAccessor, viewModel);
    },
    update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var value = valueAccessor();
        ko.bindingHandlers.value.update(element, createValueAccessor(value), allBindingsAccessor, viewModel);
    }
};

// Sample part

var viewModel = { date: ko.observable("1.1.15") };
viewModel.date.subscribe(function(newVal) {
	alert(newVal.toString());
});

ko.applyBindings(viewModel);

setTimeout(function() { viewModel.date("12.12.15") }, 1000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<input data-bind="dateValue: date" />

答案 1 :(得分:0)

这是一个有效的解决方案:

datePicker: {{ jsonDate: Document.DocumentDate, format: 'dd-MMM-yyyy' }}

   ko.bindingHandlers.datePicker = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        // Register change callbacks to update the model
        // if the control changes.       
        ko.utils.registerEventHandler(element, "change", function () {
            var value = valueAccessor();
            var dtStr = element.value;
            var fmt = ko.unwrap(value.format);

            var dt = Date.parseLocale(dtStr, fmt)
            value.jsonDate(dt);
        });
    },
    // Update the control whenever the view model changes
    update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var value = valueAccessor();
        var dtStr = ko.unwrap(value.jsonDate);
        var fmt = ko.unwrap(value.format);

        element.value = new Date(dtStr).localeFormat(fmt);
    }
};

根据这里的帖子: Using Knockout.js how do bind a Date property to a HTML5 date picker?