Extjs:在TabPanel中重复使用同一个网格

3
在一个 Extjs 应用程序中,我有一个网格和一个覆盖它的选项卡行。网格的内容取决于所选择的选项卡。假设选项卡有一月-二月-三月-...等值。点击选项卡时,我会重新加载网格的存储。
问题:是否可以避免复制 12 个网格组件,而是拥有一个共享实例?
谢谢。
免责声明:在 Sencha 的论坛、Google 和 Stackoverflow 上搜索都没有成功 :(
6个回答

2

虽然可以这样做,但需要付出的努力超过了其价值。建议创建组件原型,这样您就可以快速创建新实例。


是的,这是一种显而易见的方法,但我正在考虑非贪婪应用。我担心我不得不插入太多的制表符/网格,导致不必要的资源浪费。 - olegtaranenko
如果您使用延迟实例化(使用Ext.reg()将您的类注册为新的xtype),则只有在选择选项卡时,您的网格才会被实际创建,因此这将有所帮助。您还可以放弃使用十二个选项卡,而是使用一个面板和下拉菜单(或其他小部件)来选择月份。 - Mchl
这个问题到目前为止仍然是有效的。我在ExtJs 4中使用 dockedItemsboxreadyresize 来使高度覆盖整个主体区域。请参见我的答案。 - CallMeLaNN

0
希望以下实现能够满足您的需求: 1. 创建您自定义的网格并注册它 2. 将其放置在选项卡面板中
由于该网格是使用xtype创建的,因此在更改选项卡时不会创建12个实例。
 Application.PersonnelGrid = Ext.extend(Ext.grid.GridPanel, {
         border:false
        ,initComponent:function() {
            Ext.apply(this, {
                 store:new Ext.data.Store({...})
                ,columns:[{...}, {...}]
                ,plugins:[...]
                ,viewConfig:{forceFit:true}
                ,tbar:[...]
                ,bbar:[...]
            });

            Application.PersonnelGrid.superclass.initComponent.apply(this, arguments);
        } // eo function initComponent

        ,onRender:function() {
            this.store.load();

            Application.PersonnelGrid.superclass.onRender.apply(this, arguments);
        } // eo function onRender
    });

    Ext.reg('personnelgrid', Application.PersonnelGrid);

    var panel = new Ext.TabPanel({
                    items:[{  
                            title:'Jan', 
                            items: [{xtype:'personnelgrid'}]
                          }, { 
                            title: 'Feb', 
                            items: [{xtype:'personnelgrid'}]
                          }
                          ....
                           {
                             title: 'Dec',
                             items: [{xtype:'personnelgrid'}] 
                           }] 
                  }) 

shivashankar,感谢您的回答。在启动时 - 您是正确的,它不会创建任何实例。稍后它将创建一个新的点击选项卡 - 新的网格实例将被创建。这是Mchl建议的相同解决方案。 - olegtaranenko

0

因为这是目前唯一讨论这个问题的地方,我来分享一下我刚找到的。

诀窍就是在ExtJs 4中使用dockedItems(不确定在ExtJs 3中是否可以将grid添加到tbar)。当改变活动选项卡时,只有主体会被更改,而不是docked item。只需在boxreadyresize期间将grid的高度设为与主体相同,这样我们就看不见主体了。

这是适用于ExtJs 4.2 MVC并且还使用了refs的代码。

Ext.define('app.controller.Notification', {
extend: 'Ext.app.Controller',
views: ['notification.List'],
stores: ['Notification'],
models: ['Notification'],

refs: [{
    ref: 'pnlNotif',
    selector: 'pnlNotif'
}, {
    ref: 'notifList',
    selector: 'notifList'
}],

init: function () {
    this.control({
        'dbPnlNotif': {
            added: this.pnlNotifAdded,
            boxready: this.calcNotifListSize,
            resize: this.calcNotifListSize,
            tabchange: this.pnlNotifTabChange
        }
    });
},

pnlNotifAdded: function (pnlNotif) {
    pnlNotif.add({ title: '1', html: '1' });
    pnlNotif.add({ title: '2', html: '2' });
    pnlNotif.add({ title: '3', html: '3' });
},

calcNotifListSize: function (pnlNotif) {
    // calc the notification list height to make sure it use the whole body
    // This way we can use only one instance of list to display for each tabs
    // because the list is rendered as dockedItems
    var height = pnlNotif.getHeight();
    var headerHeight = pnlNotif.getDockedItems()[0].getHeight();
    var tabBarHeight = pnlNotif.getDockedItems()[1].getHeight();
    height = height - headerHeight - tabBarHeight;
    if (this.getNotifList().getHeight() !== height) {
        this.getNotifList().setHeight(height - 1);// - 1 to include border bottom
    }
},

pnlNotifTabChange: function (pnlNotif, newTab) {
    // do something to filter the list based on selected tab.
}
});

Ext.define('ML.view.Notification', {
extend: 'Ext.tab.Panel',
alias: ['widget.pnlNotif'],
title: 'Notification',

dockedItems: [{
    xtype: 'notifList'
}]
});

Ext.define('ML.view.notification.List', {
extend: 'Ext.grid.Panel',
alias: 'widget.notifList',
dock: 'top',
store: 'Notification',

initComponent: function () {
    this.columns = [
        ...
    ];
    this.callParent(arguments);
}
});

0

试试这个

    var gridJanName = Ext.create('Ext.grid.Panel', {
        enableColumnHide: false,
        autoScroll:true,
        store: storeJanNameGroup,
        border:true,
        stripeRows: true,
        columnLines:false,
        loadMask: true,
        tbar:tbgridTools,
        margin: '1 1 1 1',
        pageSize: 100,
        maxWidth:700,
        features: [groupFeature],
        selModel: {
            mode: 'MULTI'
        },
        columns: [
            {xtype:'rownumberer',width:50},
            {dataIndex:'id', hidden:true},
        //etc
        ]
    }); 
        var gridFebName = Ext.create('Ext.grid.Panel', {
        enableColumnHide: false,
        autoScroll:true,
        store: storeJanNameGroup,
        border:true,
        stripeRows: true,
        columnLines:false,
        loadMask: true,
        tbar:tbgridTools,
        margin: '1 1 1 1',
        pageSize: 100,
        maxWidth:700,
        features: [groupFeature],
        selModel: {
            mode: 'MULTI'
        },
        columns: [
            {xtype:'rownumberer',width:50},
            {dataIndex:'id', hidden:true},
        //etc
        ]
    });
    //
    //etc grid
    //


    var JanPanel = Ext.create('Ext.panel.Panel', {
        title:'Jan',
        bodyPadding: 5, 
        Width:780,
        layout: {
            type: 'hbox',
            align: 'stretch'
        },
        items: [gridJanName]
    });
    var FebPanel = Ext.create('Ext.panel.Panel', {
        title:'Feb',
        bodyPadding: 5, 
        Width:780,
        layout: {
            type: 'hbox',
            align: 'stretch'
        }
        //,items: [gridFebName]
    });
    var MarPanel = Ext.create('Ext.panel.Panel', {
        title:'Mar',
        bodyPadding: 5, 
        Width:780,
        layout: {
            type: 'hbox',
            align: 'stretch'
        }
        //,items: [gridMarName]
    });
    //etc
    var eachMonthstabs = Ext.create('Ext.tab.Panel', {
        minTabWidth: 130,
        tabWidth:150,
        //Width:750,
        scroll:false,
        autoHeight: true,
        id:'timestabs',
        enableTabScroll:true,
        items: [
            {
                xtype:JanPanel
            },
            {
                xtype:FebPanel
            },
            {
                xtype:MarPanel
            }
            ///etc
            ]
    });

为了更好地帮助用户理解,请添加一些解释。 - Kundan

0
对我来说,一个好的解决方案是使用一个名为lbar的左侧工具栏,带有按钮列表和单个网格,而不是选项卡面板。

0

我自己没有尝试过,但我想你可以创建一个带有空选项卡的TabPanel,并调整TabPanel的大小,以便仅显示选项卡条。在此之下(使用适当的布局、边框、vbox等),创建您的GridPanel,并使用TabPanel的activate事件根据当前活动选项卡重新加载网格。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接