Knockout.js 具有计算属性的敲除映射嵌套数组

Knockout.js 具有计算属性的敲除映射嵌套数组,knockout.js,knockout-mapping-plugin,Knockout.js,Knockout Mapping Plugin,我需要计算一组datetimes服务器端,允许更改日期/时间客户端。 下面的代码根据加载服务器数据工作,并将我需要的iso字段添加回服务器 当用户更改日期/时间输入字段时,如何使iso字段动态可计算 目前为止的淘汰赛: var ViewModel = function() { var self = this; // ...other first-level observables and funct function scadenzeNuove(payload) {

我需要计算一组datetimes服务器端,允许更改日期/时间客户端。 下面的代码根据加载服务器数据工作,并将我需要的iso字段添加回服务器

当用户更改日期/时间输入字段时,如何使iso字段动态可计算

目前为止的淘汰赛:

var ViewModel = function() {
    var self = this;
    // ...other first-level observables and funct

    function scadenzeNuove(payload) {
    ko.mapping.fromJS(payload, {}, this);

    this.iso = ko.pureComputed( function() {
                var data_re = /^(\d{2})\/(\d{2})\/(\d{4})T(\d{2}):(\d{2})/;
                if (!payload.data) {
                    return false;
                };
                var data_string = payload.data;

                if (!payload.ora) {
                    data_string = data_string + 'T00:00';
                } else {
                    data_string = data_string + 'T' + payload.ora;
                };

                var data_match = data_re.exec(data_string) ? data_re.exec(data_string) : false;
                if (!data_match) { return false; };
                var data = new Date(data_match[3], data_match[2]-1, data_match[1], data_match[4], data_match[5])
                return data;
    }, this);

    };
    var scadenzeNuoveMapping = {
        create: function(options) {
            return new scadenzeNuove(options.data);
        },
    };

    self.scadenzeNuove = ko.observableArray();
    self.compScadenze = function(form) {
    $.getJSON('{{ compute_scadenza }}', $(form).serialize(), function(data){
        ko.mapping.fromJS(data, scadenzeNuoveMapping, self.scadenzeNuove);
    });
    };
};
var vm = new ViewModel()
ko.applyBindings(vm);
Html:



我会使用默认构造函数从ISO字符串转到viewmodel,首先使用独立的年、月等观察值

然后,您可以定义一个computed
isoString
属性,将这些属性重新组合成一个可以发送到服务器的字符串

我强烈建议您要么编写一些可靠的测试,要么使用矩.js,如果您正在使用
Date
s

const DateTimeSelection=函数(isoString){
const date=新日期(isoString);
今年=可观察到(
date.getFullYear()
).extend({num:true});
本月=可观察(
date.getMonth()
).extend({num:true});
this.date=ko.observable(
date.getDate()
).extend({num:true});
这个小时=可观察到(
date.getHours()
).extend({num:true});
this.isoString=ko.pureComputed(()=>
新日期(
this.year()、this.month()、this.date()、this.hour()
).toISOString()
);
this.hasChanged=ko.pureComputed(()=>
this.isoString()!==isoString
);
};
ko.extenders.numeric=函数(目标){
返回ko({
阅读:目标,
写入:x=>target(数字(x))
});
};
const initialServerData=“2017-06-16T14:00:00.000Z”;
const vm=new DateTimeSelection(initialServerData);
ko.应用绑定(vm)

未被用户更改

已被用户更改
我的错误:我引用了静态数据
有效负载
,而不是动态可观察的
父级

function ScadenzeNuove(payload) {
    var parent = this;
    ko.mapping.fromJS(payload, {}, parent);

    parent.iso = ko.pureComputed( function() {
        var data_re = /^(\d{2})\/(\d{2})\/(\d{4})T(\d{2}):(\d{2})/;
        if (!parent.data()) {
            console.log("Not entered any date");
            return false;
        };
        var data_string = parent.data();

        if (!parent.ora()) {
            data_string = data_string + 'T00:00';
        } else {
            data_string = data_string + 'T' + parent.ora();
        };

        var data_match = data_re.exec(data_string) ? data_re.exec(data_string) : false;
        if (!data_match) {
            console.log('Not a valid date format');
            return false;
        };

        console.log(data_match);

        // Array [ "08/06/2017T23:50:00", "08", "06", "2017", "23", "50" ]
        var data = new Date(data_match[3], data_match[2]-1, data_match[1], data_match[4], data_match[5])
        console.log(data.toLocaleFormat());
        console.log(data.getTimezoneOffset());
        return data;
    }, parent);


    parent.toCal = ko.observable(false);
};

我想问题是iso属性没有被映射,因为映射调用发生在。。。但我不知道如何应用正确的计时…我尝试使用一个裸的ko.computed,如中所示,但仍然不起作用:iso字段不会随着组件字段值的变化而更新。我的问题是如何使用ko.mapping.fromJS映射json数组,而不是将js日期时间弄乱,我想我没有很好地解释我的视图。。。我试图解释的是,使用ISO日期字符串在viewmodels和服务器模型之间进行通信更容易。即:接收一个
日期时间
ISO字符串,为其创建一个viewmodel,该viewmodel创建
等输入,然后在最后转换回ISO字符串。另外,我要说的是,使用正则表达式解析ISO字符串比使用实际用于解决此类问题的语言功能更“搞乱js日期时间”…明白你的意思了,谢谢。然而,我的代码崩溃了,因为我没有管理正确的javascript函数范围。
function ScadenzeNuove(payload) {
    var parent = this;
    ko.mapping.fromJS(payload, {}, parent);

    parent.iso = ko.pureComputed( function() {
        var data_re = /^(\d{2})\/(\d{2})\/(\d{4})T(\d{2}):(\d{2})/;
        if (!parent.data()) {
            console.log("Not entered any date");
            return false;
        };
        var data_string = parent.data();

        if (!parent.ora()) {
            data_string = data_string + 'T00:00';
        } else {
            data_string = data_string + 'T' + parent.ora();
        };

        var data_match = data_re.exec(data_string) ? data_re.exec(data_string) : false;
        if (!data_match) {
            console.log('Not a valid date format');
            return false;
        };

        console.log(data_match);

        // Array [ "08/06/2017T23:50:00", "08", "06", "2017", "23", "50" ]
        var data = new Date(data_match[3], data_match[2]-1, data_match[1], data_match[4], data_match[5])
        console.log(data.toLocaleFormat());
        console.log(data.getTimezoneOffset());
        return data;
    }, parent);


    parent.toCal = ko.observable(false);
};