【问题标题】:Dynamically switch views in ExtJS 4 grid panel在 ExtJS 4 网格面板中动态切换视图
【发布时间】:2012-10-27 20:23:18
【问题描述】:

ExtJS 4 网格面板需要动态改变视图。

默认情况下,网格显示为表格,但在我的应用程序中,我需要一个功能来将网格从​​表格视图切换到 tiles(或 cards)视图。下面我试图表示它应该是什么样子。

 Normal view:                               Tiles view:
 ======================================     ====================================
 | Name       | Description           |     | Name       | Description         |
 ======================================     ====================================
 | Name 1     | First description   |^|     |  ------     ------     ------  |^|
 |----------------------------------|X|     | | O  O |   | @  @ |   | >  < | |X|
 | Name 2     | Second description  |X|     | | \__/ |   | \__/ |   | \__/ | |X|
 |----------------------------------|X|     |  ------     ------     ------  |X|
 | Name 3     | Third description   | |     |  Name 1     Name 2     Name 3  | |
 |----------------------------------| |     |                                | |
 |            |                     | |     |  ------     ------     ------  | |
 | ...        | ...                 |v|     | | o  O |   | -  - |   | *  * | |v|
 ======================================     ====================================

我找到了我所需要的几乎完美的实现,命名为Ext.ux.grid.ExplorerView。但是,该扩展是为 ExtJS 版本 2.x (3.x) 开发的,不能重复用于 ExtJS 4。

我使用了一个简单的网格:

Ext.create("Ext.grid.Panel", {
    store: ...,
    columns: [{
        header: "Name",
        dataIndex: "name",
    }, {
        header: "Description",
        dataIndex: "description"
    }],
    tbar: [ ... ],
    bbar: [ ... ],
    listeners: { ... },
    multiSelect: true,
    viewConfig: {
        stripeRows: true,
        markDirty: false,
        listeners: { ... }
    }
});

我尝试更新内部视图组件的tpl 属性,但似乎没有任何效果。

您知道如何在单个网格面板的视图之间进行动态切换

【问题讨论】:

    标签: javascript extjs extjs4


    【解决方案1】:

    使用Harald Hanek 开发的名为“Tileview”的网格面板的精彩功能 轻松解决了这个问题。该解决方案专为 ExtJS 4 开发。

    基本用法示例为:

    var grid = Ext.create("Ext.grid.Panel", {
        store: ...,
        columns: [{
            header: "Name",
            dataIndex: "name",
        }, {
            header: "Description",
            dataIndex: "description"
        }],
        tbar: [ ... ],
        bbar: [ ... ],
        listeners: { ... },
        multiSelect: true,
        viewConfig: {
            stripeRows: true,
            markDirty: false,
            listeners: { ... }
        },
    
        features: [Ext.create("Ext.ux.grid.feature.Tileview", {
            getAdditionalData: function(data, index, record, orig) {
                if (this.viewMode) {
                    return {
                        name: record.get("name").toLowerCase(),
                    };
                }
                return {};
            },
            viewMode: 'tileIcons',   // default view
            viewTpls: {
                tileIcons: [
                    '<td class="{cls} ux-tileview-detailed-icon-row">',
                    '<table class="x-grid-row-table">',
                        '<tbody>',
                        '<tr>',
                            '<td class="x-grid-col x-grid-cell ux-tileview-icon" style="background-image: url(&quot;...&quot;);">',
                            '</td>',
                            '<td class="x-grid-col x-grid-cell">',
                                '<div class="x-grid-cell-inner">{name}</div>',
                            '</td>',
                        '</tr>',
                        '</tbody>',
                    '</table>',
                    '</td>'
                ].join(""),
    
                mediumIcons: [ ... ].join(""),
                largeIcons: [ ... ].join("")
            }
        })]
    });
    

    要更改视图,我们应该只使用setView() 方法,即

    grid.features[0].setView("tileIcons");
    

    这就是该功能在现实生活中的样子。

    • 平铺视图示例:

    • 图像视图示例:


    参考资料:

    【讨论】:

    • 这个插件仍然不支持 Extjs 4.2。
    【解决方案2】:

    我不会那样做的。取而代之的是,在卡片布局中有一个网格和一个视图,该视图使您能够对每个项目进行几乎任何标记,这是一个简单的示例:

    Ext.define('Thing', {
        extend: 'Ext.data.Model',
        fields: ['name']
    });
    
    Ext.require('*');
    
    Ext.onReady(function() {
    
        var store = Ext.create('Ext.data.Store', {
            model: Thing,
            data: [{
                name: 'Name 1'
            }, {
                name: 'Name 2'
            }, {
                name: 'Name 3'
            }]
        });
    
        var gridActive = true;
    
        var panel = Ext.create('Ext.panel.Panel', {
            renderTo: document.body,
            width: 400,
            height: 400,
            layout: 'card',
            tbar: [{
                text: 'Switch',
                handler: function(){
                    var item;
                    if (gridActive) {
                        item = panel.items.last();
                    } else {
                        item = panel.items.first();
                    }
                    gridActive = !gridActive;
                    panel.getLayout().setActiveItem(item);
                }
            }],
            items: [{
                border: false,
                xtype: 'gridpanel',
                columns: [{
                    text: 'Name',
                    dataIndex: 'name'
                }],
                store: store
            }, {
                xtype: 'dataview',
                itemTpl: '<b>{name}</b>',
                store: store
            }]
        });
    
    });
    

    【讨论】:

    • 感谢 Evan,您提供了出色的替代解决方案。但是,我想,在内存中有两个视图可能效率不高。我找到了另一个不错的选择。有兴趣的可以看看我的回答here
    • 有了 tileview,你的内存中仍然有 2 个视图,基本上是一样的。
    • 并非如此。根据消息来源,它只是替换了位于网格下方的视图中的模板。
    • 像这样进入和修改内部结构是非常糟糕的做法,添加另一个视图几乎没有任何额外开销,而且肯定是一种更正确和可扩展的方式。
    • @VisoN 这个答案更简洁,不依赖于未记录的功能
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-15
    • 2011-08-06
    • 2011-11-14
    • 1970-01-01
    • 1970-01-01
    • 2021-01-09
    相关资源
    最近更新 更多