Knockout.js 敲除映射-不想创建对象,但需要序列化它

Knockout.js 敲除映射-不想创建对象,但需要序列化它,knockout.js,knockout-mapping-plugin,Knockout.js,Knockout Mapping Plugin,因为我需要访问页面上的月、日和年,所以我有一个带有复合对象SplitDate的viewmodel var SplitDate = function(date) { var _date = ko.observable(); // the backing field this.date = ko.computed({ read: _date, write: setDate }); this.year = ko.computed({ read: makeGe

因为我需要访问页面上的月、日和年,所以我有一个带有复合对象SplitDate的viewmodel

var SplitDate = function(date) {
       var _date = ko.observable(); // the backing field

       this.date = ko.computed({ read: _date, write: setDate });
       this.year = ko.computed({ read: makeGetter('year'), write: makeSetter('year') });
       this.month = ko.computed({ read: getMonth, write: setMonth });
       this.day = ko.computed({ read: makeGetter('date'), write: makeSetter('date') 

       // not showing setters/getters, etc.
       ....
    });
}
在我的视图模型上,我使用这个对象如下

self.trainingEndDate = ko.observable(new SplitDate());
我遇到的问题是,我需要能够为同一页面多次映射来自ajax调用的新数据。我试着允许敲除映射每次创建一个新的SplitDate,但没有成功。显然,被删除和替换的SplitDate是绑定到页面的日期

因此,我创建了一个映射,该映射将忽略作为拆分日期的viewmodel项目,对于这些项目,我只更新现有控件的日期

在我需要打开模型并使用ajax调用发布它之前,这一切都很好。敲除映射在忽略属性上设置一个标志,因此这些属性不会包含在未映射的对象中。我正在使用一个不同的映射选项,它不会忽略它们,我还尝试在使用include选项时添加它们,但不起作用

为什么显式包含不能取代隐式忽略?我是否应该忽略映射上的这些对象?有没有一个选项可以用来调用日期的设置器,而不是忽略它们


在我之前,但是SplitDate中是否有我需要包含的内容,以确保在我获得映射以实际包含它之后它被正确序列化?

如果您将成员直接附加到可观察对象,映射将忽略它们。也许以下方法更适合您的需要

var CreateSplitDate = function(date) {
     var _date = ko.observable(); // the backing field

     _date.date = ko.computed({ read: _date, write: setDate });
     _date.year = ko.computed({ read: makeGetter('year'), write: makeSetter('year') });
     _date.month = ko.computed({ read: getMonth, write: setMonth });
     _date.day = ko.computed({ read: makeGetter('date'), write: makeSetter('date') 

     // not showing setters/getters, etc.
     ....

     return _date;
};
然后使用:

self.trainingEndDate = ko.observable(CreateSplitDate());
这将使您能够像使用现有方法一样处理计算出的可观测值。但是,当您调用ko.mapping.toJS时,您附加到TrainingEndate的成员将被忽略

下面是这种行为的一个简单示例:


希望这有帮助

我在尝试用新实例替换对象实例时也遇到过类似的问题。我的猜测是,当完成此操作时,KO的绑定确实丢失了。然而,从您的情景来看,我认为任务包括:

将日期实体分解为天、月和年,而不会在发送到服务器时使用这些单独的实体污染主viewmodel

当时想到的最合乎逻辑的解决方案是一个组件,它可以完全避免映射问题,并在VM之外处理数据,而不是作为子属性。将单个属性作为数据传递,组件将在其自己的、未映射的viewModel中对其进行处理和可视化。例如,假设您检索和存储的唯一数据是DD/MM/YYYY格式的字符串。这是您的最小VM:

var jsonData = '09/10/2015';
var app = {date: ko.observable(jsonData)};
ko.applyBindings(app);

现在,您的splitDate对象可以用作datepicker或viewer组件模型的VM。我不知道你的getter和setter的背后是什么,但是我做了一点,使用了一些非常基本的验证的可写计算

您是否可以包含实际执行映射/序列化/反序列化的代码?因此,虽然我比我所拥有的代码更喜欢您的代码,但它对敲除映射确实没有帮助。如果我在映射时忽略属性,包括在取消映射时忽略属性,仍然不起作用。如果我没有忽略它们,映射程序仍然会删除对象并创建一个新对象。可能是我在应用你的代码时做错了什么,但我时间紧迫,不能再玩了。我最终忽略了映射上的属性,然后在取消映射时手动对它们进行编码。@SteveWash-您介意发布一个JSFIDLE示例来说明您所做的工作吗?我会尽力做到这一点,但非常困难。技术主管辞职了,而我实际上是接替者。