淘汰映射 - 不想创建对象但需要序列化它

时间:2015-02-10 15:14:02

标签: knockout.js knockout-mapping-plugin

因为我需要在我的页面上访问月,日和年,所以我有一个带有复合对象的视图模型,SplitDate。

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调用中的新数据。我尝试每次都允许Knockout Mapping创建一个新的SplitDate,但这不起作用。显然,被删除和替换的SplitDate是绑定到页面的那个。

所以我创建了一个映射,它将忽略作为SplitDates的viewmodel特性,对于那些我只更新现有控件的日期。

这很好,直到我需要打开模型并使用ajax调用发布它。 Knockout Mapping在ignore属性上设置一个标志,因此它们不包含在未映射的对象中。我使用了不会忽略"的不同映射选项。他们和我也尝试使用" include"添加它们。选项但是没有用。

为什么不明确"包括"取代隐含的"忽略"?我不应该忽略映射上的这些对象吗?我可以使用一个选项来调用日期的setter而不是忽略它们吗?

领先于自己,但是我需要在SplitDate中包含哪些东西以确保在我实际包含它之后它被正确序列化了?

2 个答案:

答案 0 :(得分:0)

如果将成员直接附加到可观察对象,则映射将忽略它们。也许以下方法可以更好地满足您的需求?

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时,您附加到trainingEndDate的成员将被忽略。

以下是此行为的简单示例:http://jsfiddle.net/c46gknfj/

希望这有帮助!

答案 1 :(得分:0)

我尝试用新的对象实例替换对象实例时遇到了类似的麻烦。我的猜测是,当完成时,KO的绑定确实会丢失。但是,根据您的情况,在我看来,作业包括:

  

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

当时想到的最合理的解决方案(以及处理您的VM的 之外的数据而不是子属性)是组件< / strong>(这将完全避免映射问题)。您将单个属性作为数据传递,组件处理并在其自己的非映射viewModel中将其可视化。例如,让我们说您检索和存储的唯一数据是DD/MM/YYYY格式的字符串。这是你非常小的VM:

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

现在,您的splitDate对象可以用作datepicker(或查看器)组件模型的VM。我不知道你的getter和setter背后有什么,但我做了一点test case here,使用可写的计算机进行了一些非常基本的验证。