在剔除视图模型中绑定日期时间

时间:2018-09-20 00:24:03

标签: knockout.js event-handling bootstrap-datetimepicker

我尝试了所有可能遇到的可能性,但datepicker并未触发视图模型的更新。经过搜索,我可以将以下内容汇总在一起:

ko.bindingHandlers.datepicker = {
    init: function (element, valueAccessor, allBindings) {
        //initialize datepicker with some optional options
        var options = allBindings.get('options') || {
            format: 'DD MMMM YYYY',
            defaultDate: valueAccessor()()
        };

        $(element).datetimepicker(options);

       ko.utils.registerEventHandler(element, "changeDate", function (event) 
       {
           var value = valueAccessor();
           if (ko.isObservable(value)) {
              value(event.date);
           }
       });
    },
    update: function (element, valueAccessor) {
        var widget = $(element).data("DateTimePicker");
        var value = ko.unwrap(valueAccessor()); //I can see the initial value when page first load

        if (widget) {
            widget.date = value;
            if (widget.date) {
                $(element).datetimepicker({
                    date: value
                });
            }
       }
    }
};


var viewModel = ko.mapping.fromJS(data, mapping);

// continue with some tweaking

 // DateOfThing comes from c# DateTime type

 // on console window
 // ko.isObservable(viewModel.DateOfThing) // = true

  vm.DateOfThing.subscribe(function(){
    // never fires
  }

绑定:

<input asp-for="DateOfThing" class="form-control" type="text" data-bind="datepicker: DateOfThing" />

我可以看到在第一次加载页面时调用了处理程序,但是UI没有更新。此后我可以选择一个日期,但是只有UI会更新。我尝试了所有可能遇到的所有可能性,但均未成功。

1 个答案:

答案 0 :(得分:0)

docs中,他们已经给出了创建Knockout处理程序的部分。尝试与您比较一下吗?特别是事件dp.change的名称,而不是changeDate

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

        //when a user changes the date, update the view model
        ko.utils.registerEventHandler(element, "dp.change", function (event) {
            var value = valueAccessor();
            if (ko.isObservable(value)) {
                if (event.date != null && !(event.date instanceof Date)) {
                    value(event.date.toDate());
                } else {
                    value(event.date);
                }
            }
        });

        ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
            var picker = $(element).data("DateTimePicker");
            if (picker) {
                picker.destroy();
            }
        });
    },
    update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {

        var picker = $(element).data("DateTimePicker");
        //when the view model is updated, update the widget
        if (picker) {
            var koDate = ko.utils.unwrapObservable(valueAccessor());

            //in case return from server datetime i am get in this form for example /Date(93989393)/ then fomat this
            koDate = (typeof (koDate) !== 'object') ? new Date(parseFloat(koDate.replace(/[^0-9]/g, ''))) : koDate;

            picker.date(koDate);
        }
    }
};