【问题标题】:How can I create a typed collection class in Knockout mapping?如何在 Knockout 映射中创建类型化集合类?
【发布时间】:2015-01-09 10:23:37
【问题描述】:

我正在使用带有mapping plugin 的淘汰赛,这样我就可以编写如下代码:

function ContactViewModel() {
    //other properties...
    this.emails = ko.observableArray();
}

function ContactEmailViewModel() {
    //other properties...
    this.address = ko.observable();
}

var koContactMap = {
    'emails': {
        create: function (options) {
                    return new ContactEmailViewModel(options.data);
        }
    }
};

var model = new ContactViewModel();
ko.mapping.fromJS([JSON data from web service], koContactMap, model);

在英语中,我有contactsemails,而contactemails

这非常有效,我可以加载联系人并填充数据和电子邮件,并且电子邮件的类型为 ContactEmailViewModel,如我所愿。

但我感到困惑的是:为什么 map create 方法返回一个 singular 电子邮件对象,而不是一个 collection 电子邮件对象。 emails 属性是一个集合,但似乎是通过返回单个对象来填充的,并且被多次调用,每个成员调用一次。

这会正确填充emails 属性。但是现在我想将 emails 从一个数组更改为一个 EmailsList 对象,这样我就可以给它方法,但我看不到如何做到这一点,因为 create 方法返回的是单个电子邮件,而不是整个电子邮件属性。

【问题讨论】:

    标签: ajax json knockout.js knockout-mapping-plugin


    【解决方案1】:

    对于这种行为,您可以在电子邮件属性上添加 ignore,并让映射插件将电子邮件映射到您提供给 EmailsList 构造函数的标准数组中。

    var emailMapping = {
       create: function(opt) {
          return new Email(opt.data);
       }
    };
    
    this.emails = new EmailList(ko.mapping.fromJS(arr, emailMapping));
    

    嗯,您还可以使用 observableArray 扩展一个自定义类,我认为(尚未测试) ko.mapping 只会将电子邮件添加到您的 EmailList 中,例如

    this.emails = new EmailList(); //This is is a ko.observableArray the mapping plugin will populate it with emails
    ko.mapping.fromJS(data, mappingInfo, this);
    

    https://github.com/knockout/knockout/blob/master/src/subscribables/observableArray.js

    更新:我刚刚确认解决方案二有效,所以我会说这是一个很好的方法

    http://jsfiddle.net/xop2go2z/

    //stolen from ko source
    function setPrototypeOf(obj, proto) {
            obj.__proto__ = proto;
            return obj;
        }
    
    ko.MyList = function(arr) {
        var result = ko.observableArray(arr);
        return setPrototypeOf(result, ko.MyList.fn);
    }
    
    ko.MyList.fn = {
        pushMyThingy: function(obj) {
            this.push(obj);
        }
    };
    

    【讨论】:

    • 我知道如何使用ignore,但我不知道您将在何处放置用于创建和返回 EmailsList 对象的代码,以及它将从何处获取电子邮件对象数据。你能建议一些代码来做到这一点吗?
    • 查看更新,详细,但我认为这是当前版本映射的唯一方法
    • 查看可能的第二种解决方案
    猜你喜欢
    • 1970-01-01
    • 2011-09-24
    • 1970-01-01
    • 1970-01-01
    • 2019-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多