在 ExtJS 4 网格面板中动态切换视图

5
需要在 ExtJS 4 grid panel 中动态更改视图。 默认情况下,网格以表格形式显示,但在我的应用程序中,我需要一个功能来将网格从表格视图切换到瓷砖(或卡片)视图。下面我尝试展示它应该是什么样子。
 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 属性,但似乎没有任何作用。 你有任何想法如何实现 单个网格面板中视图之间的动态切换 吗?
2个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
5
问题很容易通过名为 "Tileview" 的网格面板的精彩特性得以解决,该特性由Harald Hanek开发。该解决方案是专门为 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");

我将展示实际应用中该功能的外观。

  • 平铺视图的示例:

enter image description here

  • 图片视图示例:

enter image description here


参考文献:


1
此插件仍不支持Extjs 4.2。 - jeewiya

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提供的出色替代方案。然而,我认为在内存中保存两个视图可能不是很高效。我已经找到了另一个好的选择。如果您有兴趣,可以查看我的答案这里 - VisioN
使用TileView时,您仍然需要在内存中保留2个视图,这基本上是相同的事情。 - Evan Trimboli
不完全是这样。根据资料,它只是替换了网格底层视图中的模板。 - VisioN
1
这样直接访问和修改内部结构是相当糟糕的做法,添加另一个视图几乎没有额外的开销,而且肯定是更正确和可扩展的方式。 - Evan Trimboli
@VisoN 这个答案更加简洁,不依赖于未记录的特性。 - Ruan Mendes

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