如何访问Extjs嵌套模型(从Xml加载)?

时间:2012-08-02 19:10:13

标签: xml model extjs4

难以理解模型的'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));
} 

但这导致未定义的引用。

我认识到它可能归结为我们错误地描述了我们的模型,但我们已经尝试过了 几十个不同的配置,无法弄清楚是否有问题 是数据没有进入商店...或者我们是否不能参考 语法正确。

1 个答案:

答案 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'
    }
});