代码之家  ›  专栏  ›  技术社区  ›  user590028

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

  •  2
  • user590028  · 技术社区  · 12 年前

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

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

    我们创建了一个简单的网格并将其链接到商店。。。并且在此之前, 它显示联系人(快速ascii渲染)

    +---------------------------+
    | My Grid Panel             |
    +-----+---------------------+
    | Id  | Name                |
    +-----+---------------------+
    |  1  | Bob Jones           |
    |  2  | John Rodeo          |
    

    但我们完全不知道如何检索相关的电子邮件 记录。

    我读到GridPanel可能无法正确呈现关联 数据这对我们来说没问题——我们只是想清醒一下 我们如何使用这个模型数据以编程方式访问它。

    例如,假设我们想创建一个附加的简单onXmlstoreLoad事件 到商店,我们只想在加载后控制台.log()电子邮件地址 --正确的语法是什么?

    我们尝试了推荐的方法:

    onXmlstoreLoad: function(store, records, successful, operation, options) {
        console.log(store.emailAddresses.getAt(0));
    } 
    

    但这导致了一个未定义的引用。

    我知道这可能归结为我们对模型的描述不正确,但我们已经尝试过了 几十种不同的配置,无法确定问题是否存在 数据没有进入存储。。。或者我们是否不能参考 语法正确。

    1 回复  |  直到 12 年前
        1
  •  2
  •   user590028    12 年前

    终于弄清楚了我错过了什么,才能成功地正确阅读嵌套模型。一旦我们正确地填充了我们的存储,访问嵌套的数据记录就很简单了。

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

    我建议任何偶然发现这个帖子的人查看Neil McGuigan维护的优秀网站-- http://extjs-tutorials.blogspot.com/2012_05_01_archive.html 。这里有很多重要的提示&您应该遵循的最佳实践。

    Neil为我们的解决方案提供的一条重要线索是,开发人员应该将Proxy和Readers挂在Models上,而不是挂在商店上。这使得管理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'
        }
    });