extjs 如何在编辑器网格面板中呈现远程组合框的初始显示值?

8fq7wneg  于 2022-11-04  发布在  其他
关注(0)|答案(1)|浏览(171)

注意:我最近发布了this question,它询问了一个简单的远程组合框。这个问题是相似的,但不是重复的,因为它把远程组合框放在了一个远程网格中。
我正在呈现EditorGridPanel。其中一个列使用了ComboBox编辑器。网格和组合框从不同的HTTP端点加载各自的数据。如何强制组合列在初始加载时呈现显示字段?
我找到了一些解决方法,但似乎应该有一种更简单的方法。我的解决方法基本上是强制这些异步负载同步:首先加载组合存储,然后加载网格存储。例如,如果在一个网格中有多个远程组合,这就变得复杂了。在底层数据更改后,是否没有办法强制组合重新呈现自身?
下面是一个例子。你可以把这个代码放到任何ExtJS 3.4 Fiddle中。

// Create a remote store for the combo box.
var remoteStore = new Ext.data.JsonStore({
    url: 'https://jsonplaceholder.typicode.com/todos',
    autoLoad: true,
    fields: ['id', 'title']
});

// Create the combo box.
var remoteCombo = new Ext.form.ComboBox({
    fieldLabel: 'Remote Store (busted)',
    triggerAction: 'all',
    mode: 'local',
    store: remoteStore,
    valueField: 'id',
    displayField: 'title',
    lazyRender: true
});

// Create the column model for the grid.
var columnModel = new Ext.grid.ColumnModel(
    [{
        header: 'Column 1',
        dataIndex: 'column1',
        width: 220,
        editor: new Ext.form.TextField()
    }, {
        id: 'column2',
        header: 'Column 2',
        dataIndex: 'column2',
        width: 130,
        editor: remoteCombo,
        renderer: (value) => {
            var record = remoteCombo.findRecord(remoteCombo.valueField, value);
            return record ? record.get(remoteCombo.displayField) : 'Loading...';
        }
    }]
);

// Create a local grid store with some fake data.
var fakeData = [{
    column1: 'row 1',
    column2: 1
}, {
    column1: 'row 2',
    column2: '2'
}, {
    column1: 'row 3',
    column2: '3'
}];
var gridStore = new Ext.data.JsonStore({
    autoDestroy: true,
    autoLoad: false,
    fields: ['column1', 'column2'],
    data: fakeData
});

// Workaround #1: load grid store AFTER all required combo stores are loaded.
// remoteStore.on('load', () => gridStore.loadData(fakeData));

// Workaround #2: force the column to re-render all records after the store is loaded.
// Kludgy and also marks the records as dirty.
// remoteStore.on('load', () => {
//     gridStore.each((record) => {
//         var originalValue = record.get('column2');
//         record.set('column2', undefined);
//         record.set('column2', originalValue);
//     });
// });

// Render the grid.
new Ext.grid.EditorGridPanel({
    store: gridStore,
    cm: columnModel,
    autoExpandColumn: 'column2',
    renderTo: Ext.getBody(),
    width: 600,
    height: 300,
    title: 'Grid with remote combo',
    frame: true,
});
ffscu2ro

ffscu2ro1#

我认为你可以避免商店的同步加载。只要在网格的“render”事件中放置一个remoteStore“load”事件的监听器。类似这样:

// Create a remote store for the combo box.
var remoteStore = new Ext.data.JsonStore({
    url: 'https://jsonplaceholder.typicode.com/todos',
    autoLoad: true,
    fields: ['id', 'title']
});

// Create the combo box.
var remoteCombo = new Ext.form.ComboBox({
    fieldLabel: 'Remote Store (busted)',
    triggerAction: 'all',
    mode: 'local',
    store: remoteStore,
    valueField: 'id',
    displayField: 'title',
    lazyRender: true
});

// Create the column model for the grid.
var columnModel = new Ext.grid.ColumnModel(
    [{
        header: 'Column 1',
        dataIndex: 'column1',
        width: 220,
        editor: new Ext.form.TextField()
    }, {
        id: 'column2',
        header: 'Column 2',
        dataIndex: 'column2',
        width: 130,
        editor: remoteCombo,
        renderer: (value, metaData, record, rowIndex, colIndex, store) => {
            var recordIndex = remoteCombo.getStore().findExact(remoteCombo.valueField, value);
            var record = remoteCombo.getStore().getAt(recordIndex);
            return record ? record.get(remoteCombo.displayField) : 'Loading...';
        }
    }]
);

// Create a local grid store with some fake data.
var fakeData = [{
    column1: 'row 1',
    column2: 1
}, {
    column1: 'row 2',
    column2: 2
}, {
    column1: 'row 3',
    column2: 3
}];
var gridStore = new Ext.data.JsonStore({
    autoDestroy: true,
    autoLoad: false,
    fields: ['column1', 'column2'],
    data: fakeData
});

// Workaround #1: load grid store AFTER all required combo stores are loaded.
// remoteStore.on('load', () => gridStore.loadData(fakeData));

// Workaround #2: force the column to re-render all records after the store is loaded.
// Kludgy and also marks the records as dirty.
// remoteStore.on('load', () => {
//     gridStore.each((record) => {
//         var originalValue = record.get('column2');
//         record.set('column2', undefined);
//         record.set('column2', originalValue);
//     });
// });

// Render the grid.
new Ext.grid.EditorGridPanel({
    store: gridStore,
    cm: columnModel,
    autoExpandColumn: 'column2',
    renderTo: Ext.getBody(),
    width: 600,
    height: 300,
    title: 'Grid with remote combo',
    frame: true,
    listeners: {
        render: function (grid) {
            if (remoteStore.lastOptions === null) {
                remoteStore.on('load', function (store) {
                    grid.getView().refresh();
                }, this, {
                    single: true
                });
            }
        }
    }
});

另外,我已经修复了渲染器。另外,小心使用findExact的字符串和整数值。AFAIK是类型敏感的方法。

相关问题