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)]);
    }
});

単純なグリッドを作成してストアにリンクします...そして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));
} 

しかし、これは未定義の参照になります。

モデルの説明が間違っている可能性があることは認識していますが、数十の異なる構成を試しましたが、問題がデータがストアに入力されていないかどうか、またはデータがストアに入力されていないかどうかを判断できません。参照しないのは構文的に正しいです。

4

1 に答える 1

2

最後に、ネストされたモデルを正しく読み取ることができるようにするために私が欠けていたものを見つけました。ストアに正しくデータを入力したら、ネストされたデータレコードにアクセスするのは簡単なことでした。

私たちが見逃していた重要な部分は、プロキシ/リーダーと関係がありました。「record」および「root」パラメーターを指定できるように、各モデルには独自のプロキシリーダーが必要です。

このスレッドに出くわした人は、Neil McGuiganが管理している優れたサイト(http://extjs-tutorials.blogspot.com/2012_05_01_archive.html )をチェックすることをお勧めします。従うべき重要なヒントとベストプラクティスがたくさんあります。

Neilが私たちのソリューションに提供した重要な手がかりの1つは、開発者はプロキシとリーダーをストアからではなくモデルから切り離す必要があるということでした。これにより、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 に答える