ExtJS 4-包含没有Id关系的其他模型的模型
给定的是如下所示的嵌套模型结构:ExtJS 4-包含没有Id关系的其他模型的模型,extjs,Extjs,给定的是如下所示的嵌套模型结构: 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/whateve
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关系,因为它们直接作为列表保存在父模型中。据我所知,Ext.data.Model中的经典关系是指通过by id关系的相关模型
问题是:是否有任何方法可以告诉父模型为其图像列表中的每个子级使用图像模型 作为第一步,您可以使用
auto
字段类型将图像数据加载到模型中:
Ext.define('My.Model', {
extend: 'Ext.data.Model'
,fields: [
{name: 'images', type: 'auto'}
// ... other fields
}
});
然后:
应返回:
[
{"imageName": "Beach", "imageUrl": "http://example.com/whatever.jpg"},
...
]
从理论上讲,您应该能够实现一个完全自动化的解决方案,从这些数据创建模型,并且——最困难的部分——尝试使这些创建的记录与父模型中的子数据保持同步。但这是一个非常复杂的黑客行为,必须涵盖Ext代码库中的许多入口点。作为一个例子,我曾经尝试过为“有一个”关系这样做,这代表了。因此,我从未花时间整合这段代码,最终也从未使用过它
我更愿意提倡一种简单的局部(模型)解决方案。您可以向模型中添加一个简单的方法,以将图像作为记录。例如:
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的默认关联接口
如果需要对同一父记录多次加载图像的支持,可以使用字段的方法
最后,您可能还需要处理相关数据的客户端修改,以便能够将它们保存到服务器。如果您的关联模型允许,您可以简单地使用子存储的方法(并且不要忘记在同步回调中更新父模型的数据!)。但是,如果您的关联模型没有连接到服务器端的端点,您应该能够挂接该方法以将数据保存在关联存储中(与存储在父记录中的数据相反,如果使用关联存储,则不会更新该数据)
最后一个示例显示了这两个方面:
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;
}
});
请注意,我还没有测试这段代码,所以它可能仍然包含一些错误。。。但我希望这将足以给你一个大致的想法 太棒了!谢谢你的努力。我会在接下来的两天内尝试这个,我会带着任何反馈回来。
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;
}
});