难以理解模型的'Associations'功能以及如何使用 开发人员可以通过关联访问嵌套数据。
这是我们试图解析的简单XML文件。
<?xml version="1.0" encoding="UTF-8"?>
<contacts>
<contact>
<id>1</id>
<name>Bob Jones</name>
<emails>
<email>
<addr>bjones1@dom.com</addr>
<display>B. Jones 1</display>
</email>
<email>
<addr>bjones2@dom.com</addr>
<display>B. Jones 2</display>
</email>
</emails>
</contact>
<contact>
<id>2</id>
<name>John Rodeo</name>
<emails>
<email>
<addr>jrodeo1@dom.com</addr>
<display>J. Rodeo 1</display>
</email>
<email>
<addr>jrodeos2@dom.com</addr>
<display>J. Rodeo 2</display>
</email>
</emails>
</contact>
</contacts>
这是相关的模型
Ext.define('MyApp.model.Contact', {
extend: 'Ext.data.Model',
uses: [
'MyApp.model.Emails'
],
fields: [
{
name: 'id'
},
{
name: 'name'
}
],
hasMany: {
model: 'MyApp.model.Emails',
autoLoad: true,
foreignKey: 'addr',
name: 'emailAddresses'
}
});
Ext.define('MyApp.model.Emails', {
extend: 'Ext.data.Model',
uses: [
'MyApp.model.Contact'
],
idProperty: 'addr',
fields: [
{
name: 'addr'
},
{
name: 'display'
}
],
belongsTo: {
model: 'MyApp.model.Contact'
}
});
最后,这是商店:
Ext.define('MyApp.store.MyXmlStore', {
extend: 'Ext.data.Store',
requires: [
'MyApp.model.Contact'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
autoLoad: true,
storeId: 'MyXmlStore',
model: 'MyApp.model.Contact',
proxy: {
type: 'ajax',
url: 'data/data.xml',
reader: {
type: 'xml',
record: 'contact'
}
}
}, cfg)]);
}
});
我们创建了一个简单的网格并将其链接到商店...并且presto, 它显示了联系人(快速ascii渲染)
+---------------------------+
| My Grid Panel |
+-----+---------------------+
| Id | Name |
+-----+---------------------+
| 1 | Bob Jones |
| 2 | John Rodeo |
但是我们完全不知道如何检索相关的电子邮件 记录。
我已经读过GridPanel可能无法正确呈现关联 数据。这对我们来说没问题 - 我们只是试图让自己的头脑 我们如何使用这个模拟数据以编程方式访问它。
例如,假设我们想要创建一个简单的onXmlstoreLoad事件 到商店,我们想加载后只需console.log()电子邮件地址 - 什么是正确的语法?
我们尝试了推荐的方法:
onXmlstoreLoad: function(store, records, successful, operation, options) {
console.log(store.emailAddresses.getAt(0));
}
但这导致未定义的引用。
我认识到它可能归结为我们错误地描述了我们的模型,但我们已经尝试过了 几十个不同的配置,无法弄清楚是否有问题 是数据没有进入商店...或者我们是否不能参考 语法正确。
答案 0 :(得分:2)
最后找出了我所缺少的能够正确成功读取嵌套模型的内容。一旦我们正确填充了我们的商店,访问嵌套数据记录就很简单了。
我们失踪的关键位与代理/读者有关。每个模型都需要拥有自己的代理阅读器,以便您可以指定“记录”和“根”参数。
我建议任何偶然发现这个帖子的人都会看看Neil McGuigan维护的优秀网站 - http://extjs-tutorials.blogspot.com/2012_05_01_archive.html。有很多重要的提示&amp;你应该遵循的最佳实践。
Neil为我们的解决方案提供的一个重要线索是,开发人员应该将代理和读者关闭模型而不是商店。这使得管理Xml特定记录/根参数变得简单。
对于那些第一次进入Extjs深处的人来说,这是一个艰难的...我强烈建议你与Firebug亲密接触。步入extjs源代码开始回答很多重要的问题,关于各种位和&amp;件拼凑在一起。
extjs代码库有很好的文档记录。虽然开发人员显然是Javascript中的黑带,但偶尔会让他们无法跟上他们的目标,最终结果非常值得付出努力。
如果您正在寻找工作代码......
我们的商店
Ext.define('MyApp.store.MyXmlStore', {
extend: 'Ext.data.Store',
requires: [
'MyApp.model.Contact'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
autoLoad: true,
storeId: 'MyXmlStore',
model: 'MyApp.model.Contact',
listeners: {
load: {
fn: me.onXmlstoreLoad,
scope: me
}
}
}, cfg)]);
},
onXmlstoreLoad: function(store, records, successful, operation, options) {
console.log("onXmlstoreLoad:"+ successful);
console.log(s.getAt(0).emailAddressesStore.getAt(0));
}
});
我们的模特
Ext.define('MyApp.model.Contact', {
extend: 'Ext.data.Model',
uses: [
'MyApp.model.Emails'
],
fields: [
{
mapping: 'id',
name: 'id',
type: 'int'
},
{
mapping: 'name',
name: 'name',
type: 'string'
}
],
hasMany: {
associationKey: 'emails',
model: 'MyApp.model.Emails',
name: 'emailAddresses'
},
proxy: {
type: 'ajax',
url: 'data/data.xml',
reader: {
type: 'xml',
root: 'contacts',
record: 'contact'
}
}
});
Ext.define('MyApp.model.Emails', {
extend: 'Ext.data.Model',
uses: [
'MyApp.model.Contact'
],
fields: [
{
mapping: 'addr',
name: 'addr',
type: 'string'
},
{
mapping: 'display',
name: 'display',
type: 'string'
}
],
proxy: {
type: 'ajax',
url: 'data/data.xml',
reader: {
type: 'xml',
root: 'emails',
record: 'email'
}
},
belongsTo: {
model: 'MyApp.model.Contact'
}
});