我使用的是淘汰赛与映射插件,这样我可以写code是这样的:
I'm using knockout with the mapping plugin so that I can write code like this:
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);
在英国,我有联系人
和电子邮件
和联系人
具有电子邮件
。
In English, I have contacts
and emails
, and a contact
has emails
.
这完美的作品,我可以加载了接触,并在数据和电子邮件填充和电子邮件的类型为 ContactEmailViewModel
,因为我想要的。
This works perfectly, and I can load the contact and have the data and emails populated, and the emails are of type ContactEmailViewModel
, as I want.
但我感到困惑的是:为什么在地图创建方法返回一个奇电子邮件对象,而不是邮件对象的集。该电子邮件
属性是一个集合,但似乎是由填充返回一个对象,并多次调用,一次为每个成员。
But the thing I'm confused about is: why does the map create method return a singular email object instead of a collection of email objects. The emails
property is a collection, but seems to be populated by returning a single object, and is called multiple times, once for each member.
这正确填充电子邮件
属性。但现在我想改变电子邮件
从数组的 EmailsList
对象,这样我就可以给它的方法,和我看不出如何做到这一点,因为创建方法返回单个电子邮件,而不是整个邮件属性。
This correctly populates the emails
property. But now I want to change emails
from an array to an EmailsList
object, so that I can give it methods, and I can't see how to do this, since the create method returns individual emails, not the whole emails property.
对于这种行为,你可以添加忽略
上的邮件属性格式,让映射插件serperate映射电子邮件为你喂EmailsList构造带STANDAR阵列。
For that behaviour you can add ignore
on the emails propery and let the mapping plugin serperate map the emails into a standar array that you feed the EmailsList constructor with.
var emailMapping = {
create: function(opt) {
return new Email(opt.data);
}
};
this.emails = new EmailList(ko.mapping.fromJS(arr, emailMapping));
嗯,你也可以扩展的自定义类与observableArray我认为(还没有测试),那么ko.mapping将只需添加电子邮件到您的emailList像
Hmm, you could also extend a custom class with a observableArray I think (havent tested) that ko.mapping will then just add emails to your EmailList like
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
更新:我刚刚确认了解决方案二的工作,所以我会说这就是做一个好办法
update: I just confirmed that solution two worked, so I would say thats a good way of doing it
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);
}
};