给定的是这样的嵌套模型结构:
Model Website
+ id
+ name
+ images[] // List of Image instances
Model Image
+ imageName
+ imageUrl
响应的序列化版本如下:
{
"id": 4711,
"name": "Some name",
"images" [
{"imageName": "Beach", "imageUrl": "http://example.com/whatever.jpg"},
...
]
}
此嵌套模型集保留在文档存储中,并在Website.id请求时返回。
嵌套的图像列表没有by-id-relation,因为它们直接作为列表保存在父模型中。据我所知,Ext.data.Model中的经典关系通过by-id-relation引用相关模型。
问题是:有什么方法可以告诉父模型在其图像列表中为每个孩子使用Image模型?
答案 0 :(得分:2)
作为第一步,您可以使用字段类型auto
将图像数据加载到模型中:
Ext.define('My.Model', {
extend: 'Ext.data.Model'
,fields: [
{name: 'images', type: 'auto'}
// ... other fields
}
});
然后:
myModel.get('images');
应该返回:
[
{"imageName": "Beach", "imageUrl": "http://example.com/whatever.jpg"},
...
]
从那里,理论上你应该能够实现一个完全自动化的解决方案,从这个数据创建模型,并且 - 最难的部分 - 尝试保持这些创建的记录和父模型中的子数据同步。但这是一个非常复杂的黑客攻击,必须涵盖Ext代码库中的许多入口点。作为一个例子,我曾经试图为“有一个”关系做到这一点,代表a lot of code。结果,我从未花时间整合这段代码,最后从未使用它。
我更愿意提倡一个简单的本地(对模型)解决方案。您可以向模型添加一个简单的方法,以将图像作为记录。例如:
Ext.define('My.Model', {
// ...
,getImages: function() {
var store = this.imageStore;
if (!store) {
store = new Ext.data.Store({
model: 'My.ImageModel'
,data: this.get('images') || []
});
this.imageStore = store;
}
return store;
}
});
为相关模型创建商店将使您不必使用代理和阅读器。它还为您提供了一个接口,该接口接近Ext的默认接口。
如果您需要支持为同一个父记录多次加载图像,则可以使用该字段的convert
方法进行挂钩。
最后,您可能还需要处理关联数据的客户端修改,以便能够将它们保存到服务器。如果您的关联模型允许,您可以简单地使用子存储的sync
方法(并且不要忘记在同步回调中更新父模型的数据!)。但是,如果关联的模型未连接到服务器端的端点,则应该能够挂钩serialize
方法以将数据保存在关联的存储中(而不是存储在父存储中的数据)记录,如果您使用相关商店,将无法更新。
以下是显示两者的最后一个示例:
Ext.define('My.Model', {
extend: 'Ext.data.Model'
,fields: [
{
name: 'images'
,type: 'auto'
// enables associated data update
,convert: function(data) {
var store = this.imageStore;
if (store) {
store.loadData(data || []);
}
return data;
}
// enables saving data from the associated store
,serialize: function(value, record) {
var store = record.imageStore,
if (store) {
// care, the proxy we want is the associated model's one
var writer = store.proxy && store.proxy.writer;
if (writer) {
return Ext.Array.map(store.getRange(), function(record) {
return writer.getRecordData(record);
});
} else {
// gross implementation, simply use the records data object
return Ext.pluck(store.getRange(), 'data');
}
} else {
return record.get('images');
}
}
}
// ... other fields
}
,getImages: function() {
var store = this.imageStore;
if (!store) {
store = new Ext.data.Store({
model: 'My.ImageModel'
,data: this.get('images') || []
});
this.imageStore = store;
}
return store;
}
});
请注意我没有测试过这段代码,所以它可能仍然包含一些错误...但我希望它足以给你一般的想法!