【问题标题】:My knockout custom binding is not 2 way binding我的淘汰赛自定义绑定不是 2 路绑定
【发布时间】:2016-06-08 14:55:01
【问题描述】:

全部,

环境:

asp.net 3.5

我的日期通过 lib:Newtonsoft.json 库使用 ISO8601 格式进行序列化

目标:

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

代码如下:

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"

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

【问题讨论】:

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


    【解决方案1】:

    您可以使用扩展器来格式化日期 (Knockout.js format date item)

    或者您可以将“值”绑定与可编辑大小写的格式化函数一起包装:

    // 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" />

    【讨论】:

    • 这是一个很好的解决方案。我现在采用了另一种解决方案,但会记住这一点。
    • @ActiveX - 好的,没问题
    【解决方案2】:

    这是一个可行的解决方案:

    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?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多