Knockout.js 取消双向自定义绑定以在日期和时间字段中拆分ISO datetime

Knockout.js 取消双向自定义绑定以在日期和时间字段中拆分ISO datetime,knockout.js,Knockout.js,我在服务器端有一个日期时间字符串YYYY-MM-DDT03:00,在客户端有一个矩.js 我需要将bindinghandler的更新和初始化阶段绑定到我的observable datetime属性,但无法使其与表单输入一起工作 这是纯文本元素更新阶段的工作思路: ko.bindingHandlers.date = { update: function(element, valueAccessor) { var options = ko.unwrap(valueAccess

我在服务器端有一个日期时间字符串YYYY-MM-DDT03:00,在客户端有一个矩.js

我需要将bindinghandler的更新和初始化阶段绑定到我的observable datetime属性,但无法使其与表单输入一起工作

这是纯文本元素更新阶段的工作思路:

ko.bindingHandlers.date = {
    update: function(element, valueAccessor) {
        var options = ko.unwrap(valueAccessor);
        var value = ko.unwrap(options.value);
        var text = moment(value).format('DD/MM/YYYY');
        ko.utils.setTextContent(element, text);
    },
};
ko.bindingHandlers.time = {
    update: function(element, valueAccessor) {
        var options = ko.unwrap(valueAccessor);
        var value = ko.unwrap(options.value);
        var text = moment(value).format('HH:mm');
        ko.utils.setTextContent(element, text);
    },
};
编辑-我尝试将我的问题背景化一点

实际上,作为一个knockout和js新手,我正在尝试将EtherogenousJSON数组从服务器映射到每个项都可以通过ko.mapping具有各种属性的knockout observates。最后,我需要一个ko可观测数组,其中包含每个原始数组项的编辑/保存/取消/删除方法

function EditableCollection(payload, updateUrl) {
    /* EditableCollections = { item: actual object,
     *                         data: actual data,
     *                         edit, editing Knockout facility,
     *                       }
     */
    var collection = this;
    collection.item = ko.mapping.fromJS(payload);

    collection.editing = ko.observable(false);

    collection.edit = function() {
        if (!self.condition()) {
            // UI logic
            collection._bkp = ko.mapping.toJS(collection.item);
            collection.editing(true);
        } else {
            // UI logic
        };
    };
    collection.cancel = function() {
        ko.mapping.fromJS(collection._bkp, collection.item);
        delete(collection._bkp);
        collection.editing(false);
        // UI logic
    };
    collection.item.cancel = collection.cancel;
    collection.save = function() {
        if (updateUrl) {
        $.ajax({
            url: updateUrl,
            method:'POST',
            dataType:'json',
            data: JSON.stringify($.extend(updateData, { 'item': ko.mapping.toJS(collection.item) })), // or something
            success: function(result){
            return result;
            },
            error: function(error){
            return error;
            },
        });
        };
        // UI logic
        delete(collection._bkp);
    };
    collection.item.save = collection.save;
};
最初的问题是因为当我面对包含ISO8601字符串的数组时,我需要在两个单独的属性date和time中进行转换

所以我想我不能使用computedProperties。作为解决原始绑定方法的一种方法,我求助于在mapping create function中管理任务,但这对我来说非常低效且难看:

var scadenzeMapping = {
create: function(options) {
    var payload = options.data;
    console.log(payload);
    // ** moment.js:
    // When refactoring for TIME will matter.
    var start = moment(payload.data_start); // e.g. 05/02/2018T00:00:00
    // TODO ** Verify timezone (external) handling...
    if (payload.isAllDay) {
        payload.sdate = start.format('DD/MM/YYYY');
        payload.stime = undefined;
        payload.edate = payload.sdate;
        payload.etime = undefined;
        payload.data_end = payload.data_start;
    } else {
        payload.sdate = start.format('DD/MM/YYYY');
        payload.stime = start.format('HH:mm');
        var end = moment(payload.data_end);
        payload.edate = end.format('DD/MM/YYYY');
        payload.etime = end.format('HH:mm');
    };
    // payload.data_start = start;
    return new EditableCollection(payload,
                                  '{{ put_event }}',
                                  );
    },
};

这是原始问题的主题外上下文。

首先,您的自定义绑定不订阅传递的可观察对象的更改。如果你改变

var options = ko.unwrap(valueAccessor);

在传递的可观察对象发生更改后,将调用update函数

其次,如果您试图对输入使用此绑定,则不能使用

ko.utils.setTextContent(element, text);
因为它改变了元素的内容,而不是值。你需要使用

element.value = text;
我认为最好的方法是不使用自定义绑定,使用可写计算,使用标准值绑定,比如:

var myObservable = ko.observable();
var myComputed = ko.computed({
    write: function(val){
        myObservable(moment(val, 'DD/MM/YYYY').format('YYYY-MM-DDTHH:mm'))
    },
    read: function(){
        return moment(myObservable()).format('DD/MM/YYYY');
    }
})
在html中:

<input data-bind="value: myComputed"/>

…我想我最终会在视图模型中保留ISO格式的datetime和单独的日期和时间…几个Computed会很好地为您服务。毫无疑问,您和Ray J建议使用computedProperties是正确的,但我的问题实际上与ko.mapping有关,正如我在上面的编辑中试图解释的那样。我认为关键是在ko.bindingHandlers中使用init函数。Thanks@user2154587您不需要在ko.mapping中转换它们。您可以只存储未转换的日期,并在viewmodel中进行两次计算,将其转换为日期和时间。
<input data-bind="value: myComputed"/>