同様のシナリオがありました。独自のレコードデータ(住所、電話番号、アカウント残高など)を持つ顧客のリスト。各顧客には、一連の「有料」アイテムを持つアカウントもありました。言い換えれば、行を拡張して独自の「アカウントグリッド」を開くことができる顧客のグリッドが必要でした。これは、アイテムに関する関連データ、支払い額などを含むアイテムのグリッドを表示します。
無関係な構成やその他のコードをスリム化しましたが、「外部」グリッドに使用したビューの例を次に示します。
Ext.define('MyApp.view.CustomerGrid', {
    extend: 'Ext.grid.Panel',
    alias: 'widget.customergrid',
    requires: [
        'Ext.ux.RowExpander'
    ],
    title: 'Customer Grid',
    plugins: [{
        ptype: 'rowexpander',
        pluginId: 'rowexpander',
        selectRowOnExpand: true,
        // this gives each row a unique identifier based on record's "acct_no"
        rowBodyTpl: [
            '<div id="AccountGridRow-{acct_no}" ></div>'
        ],
        // stick a grid into the rowexpander div whenever it is toggled open
        toggleRow: function(rowIdx) {
            var rowNode = this.view.getNode(rowIdx),
                row = Ext.get(rowNode),
                nextBd = Ext.get(row).down(this.rowBodyTrSelector),
                hiddenCls = this.rowBodyHiddenCls,
                record = this.view.getRecord(rowNode),
                grid = this.getCmp(),
                acctNo = record.get('acct_no'),
                targetId = 'AccountGridRow-' + acctNo;
            if (row.hasCls(this.rowCollapsedCls)) {
                row.removeCls(this.rowCollapsedCls);
                this.recordsExpanded[record.internalId] = true;
                this.view.fireEvent('expandbody', rowNode, record, nextBd.dom);
                if (rowNode.grid) {
                    nextBd.removeCls(hiddenCls);
                    rowNode.grid.doComponentLayout();
                    rowNode.grid.view.refresh();
                } else {
                    // this is the store for the inner grid
                    Ext.create('Ext.data.Store', {
                        model: 'MyApp.model.Account',
                        proxy: {
                            type: 'ajax', 
                            url: 'customers',
                            reader: 'json'
                            extraParams: {
                                account: acctNo
                            }
                        },
                        autoLoad: {
                            callback: function() {
                                // create the inner grid and render it to the row
                                nextBd.removeCls(hiddenCls);
                                var grid = Ext.create('MyApp.view.AccountGrid', { // <-- this is my "inner" grid view
                                        renderTo: targetId,
                                        store: this,
                                        row: row
                                    });
                                rowNode.grid = grid;
                                // I didn't want to listen to events from the inner grid
                                grid.suspendEvents(); 
                            }
                        }
                    });
                }
            } else {
                row.addCls(this.rowCollapsedCls);
                nextBd.addCls(this.rowBodyHiddenCls);
                this.recordsExpanded[record.internalId] = false;
                this.view.fireEvent('collapsebody', rowNode, record, nextBd.dom);
            }
        }
    }],
    columns: [/* a bunch of column configs for the outer grid... */],
    store: Ext.getStore('StudentList') // <-- the outer grid store
});
基本的に、toggleRow関数をオーバーライドして、別のグリッド(MyApp.view.AccountGrid)をrowexpanderdivに貼り付けます。
これは非常にうまくいき、アプリはこれで完成しました。
キャッシュされたオブジェクトに内部の「アカウント」グリッドのデータがあるので、ajaxは50〜100ミリ秒以内に戻ります。内部グリッドデータを取得するためのある種の長いクエリがある場合、これは機能しないことがわかります。