如何在Knockout映射中创建类型化集合类



我在映射插件中使用敲除,这样我就可以编写这样的代码:

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

在英语中,我有contactsemailscontactemails

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

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

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

对于这种行为,您可以在电子邮件属性上添加ignore,并让映射插件seroperate将电子邮件映射到一个标准数组中,您可以使用该数组向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);
    }
};

最新更新