2

很难理解模型的“关联”功能以及开发人员如何通过关联访问嵌套数据。

这是我们试图解析的一个简单的 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)]);
    }
});

我们创建了一个简单的 Grid 并将其链接到 Store ......然后,它显示了联系人(快速 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));
} 

但这会导致未定义的引用。

我承认这可能归结为我们错误地描述了我们的模型,但是我们已经尝试了几十种不同的配置,并且无法弄清楚问题是否是数据没有进入存储......或者我们是否可以't reference 在语法上是正确的。

4

1 回答 1

2

终于弄清楚了能够正确读取嵌套模型所缺少的东西。一旦我们正确地填充了我们的存储,访问嵌套数据记录就很简单了。

我们缺少的关键部分与代理/阅读器有关。每个模型都需要有自己的代理阅读器,因此您可以指定“记录”和“根”参数。

我建议任何偶然发现此线程的人查看由 Neil McGuigan 维护的优秀网站 - http://extjs-tutorials.blogspot.com/2012_05_01_archive.html。您应该遵循大量重要的提示和最佳实践。

Neil 为我们的解决方案提供的一个重要线索是,开发人员应该将 Proxy 和 Readers 挂在模型上,而不是挂在商店之外。这使得管理 Xml 特定记录/根参数变得简单。

唷,这是一个艰难的...对于任何第一次进入 Extjs 深层的人,我强烈建议您与 Firebug 亲密接触。步入 extjs 源代码开始回答许多关于如何将各个部分组合在一起的重要问题。

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'
    }
});
于 2012-08-03T20:33:59.450 回答