【问题标题】:Knockout Mapping - Don't want to create object but need to serialize itKnockout Mapping - 不想创建对象但需要序列化它
【发布时间】:2015-04-10 16:36:10
【问题描述】:

因为我需要访问页面上的月、日和年,所以我有一个带有复合对象 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 的视图模型属性,而对于那些我只是更新现有控件的日期。

在我需要解开模型并使用 ajax 调用发布它之前,它运行良好。 Knockout Mapping 在忽略属性上设置了一个标志,因此这些属性不包含在未映射的对象中。我正在使用不同的映射选项,它不会“忽略”它们,我还尝试使用“包含”选项将它们添加到其中,但没有奏效。

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

超越我自己,但是我需要在 SplitDate 中包含一些内容以确保在我得到映射以实际包含它之后正确序列化它吗?

【问题讨论】:

  • 能否包含实际执行映射/序列化/反序列化的代码?

标签: knockout.js knockout-mapping-plugin


【解决方案1】:

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

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());

这将使您可以像使用现有方法一样对待计算出的 observables。但是,当您调用 ko.mapping.toJS 时,您附加到 trainingEndDate 的成员将被忽略。

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

希望这会有所帮助!

【讨论】:

  • 所以,虽然我比我更喜欢你的代码,但它确实对淘汰赛映射没有帮助。如果我在映射时忽略了属性,在取消映射时包括它们仍然不起作用。如果我没有忽略它们,映射器仍在删除对象并创建一个新对象。这可能是我在应用你的代码时做错了什么,但我时间紧迫,不能再玩它了。我最终忽略了映射上的属性,然后在取消映射时对其进行手动编码。
  • @SteveWash - 你介意发布一个你所做的 jsfiddle 示例吗?
  • 我会努力做到这一点,但令人难以置信的嘎吱作响。技术主管辞职,我是事实上的替代者。
【解决方案2】:

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

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

当时想到的最合乎逻辑的解决方案(以及处理虚拟机外部的数据而不是作为子属性)是组件 (这将完全避免映射问题)。您将单个属性作为数据传递,组件在其自己的非映射视图模型中处理和可视化它。例如,假设您检索和存储的唯一数据是格式为DD/MM/YYYY 的字符串。这是您的最小虚拟机:

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

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

【讨论】:

    猜你喜欢
    • 2013-03-09
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 2013-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-28
    相关资源
    最近更新 更多