Extjs:在 TabPanel 中重用相同的网格

发布于 2024-10-08 14:15:22 字数 201 浏览 4 评论 0原文

在 Extjs 应用程序中,我有一个网格和一个选项卡行。网格的内容取决于所选的选项卡。 假设选项卡具有 Jan-Feb-Mar-... 值。单击该选项卡我将重新加载网格的存储

问题:是否可以避免重复 12 个网格组件,而有一个共享实例?

谢谢

免责声明:在 sencha 论坛、google、stackoverflow 上搜索均未成功:(

in a Extjs application I have a Grid and a Tabs line over it. Content of the Grid depends on the selected Tab.
Say tabs has Jan-Feb-Mar-... values. Clicking of the Tab I would reload grid's store

Question: is it possible to avoid duplicating of the 12 grid components in favor to have one shared instance?

Thanks

Disclaimer: searching at the sencha's forum, google, stackoverflow was not successful :(

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

缱倦旧时光 2024-10-15 14:15:44

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

For me good solution was to use a left toolbar called lbar with list of buttons and a single grid instead of tabpanel

神爱温柔 2024-10-15 14:15:40

试试这个

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

Try this

    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
            ]
    });
那请放手 2024-10-15 14:15:37

由于这是迄今为止讨论此问题的唯一地方,因此我分享我刚刚发现的内容。

技巧是在ExtJs 4中使用dockedItems(不确定是否可以将任一网格添加到ExtJs 3中的tbar中)
更改活动选项卡时,只有正文会更改,而停靠项不会更改。只需在 boxreadyresize 期间将网格高度设置为等于正文,这样我们就看不到正文了。

这是 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);
}
});

Since this is the only place discussed about this until now, I share what I just found.

The trick is use dockedItems in ExtJs 4 (Not sure either grid can be added into tbar in ExtJs 3)
When changing the active tab, only body will be change but not the docked item. Just set the grid height equal to the body during boxready and resize so that we can't see the body anymore.

This is the code for ExtJs 4.2 MVC that also make use of 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);
}
});
月下伊人醉 2024-10-15 14:15:34

希望以下的实现能够满足您的需求
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'}] 
                           }] 
                  }) 

Hope the following implementation meet your needs
1. Create your custom grid and register it
2. place it tab panel

As the grid is created using xtype, it would not create 12 instances when you change tabs.

 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'}] 
                           }] 
                  }) 
唠甜嗑 2024-10-15 14:15:32

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

I haven't tried this myself, but I imagine that you could create a TabPanel with empty tabs and size the TabPanel so that only the tab strip is visible. Under that (using the appropriate layout, border, vbox, etc.) create your GridPanel and use the TabPanel's activate event to reload the grid based on the currently-active tab.

蓝戈者 2024-10-15 14:15:29

确实如此,但这需要付出比其价值更多的努力。只需为您的组件创建一个原型,以便您可以非常快速地创建新实例。

It is, but it would require more effort than it is worth. Just create a prototype for your component, so that you can create new instances really quickly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文