在Ext JS Grid的Action列的列标题中放置按钮

原文:《A button in the header of an Ext JS grid action column》

在本文,将演示如何在Grid的Action列的列标题中放置按钮。

缘起

为了显示和维护大量的数据,开发人员通常会使用Grid来显示数据,并绑定一个表单来添加或编辑记录。

要实现这个,有几种做法,例如,在Grid的顶部放置一个工具条:
这里写图片描述

在这里将演示一个完全集成的UI解决方案,它会在Action列的列标题内放置一个按钮,而在改列的单元格内放置编辑和删除按钮。

这里写图片描述

问题

Ext JS的Grid列已具有通过items配置项来定义列标题的能力:

{
    xtype: 'grid',
    columns: [{
        items: [{
            xtype: 'button',
            iconCls: 'x-fa fa-plus',
            ui: 'default-toolbar'
        }]
    }, ...]
}

问题是这种方式在使用action列(xtype:’actioncolumn’)时无效。实际上,aciton列的items配置项只能用来设置单元格的图标。

{
    xtype: 'grid',
    columns: [{
        xtype: 'actioncolumn',
        items: [{
            iconCls: 'x-fa fa-pencil' // config of icons in the column cells
        }, {
            iconCls: 'x-fa fa-trash'
        }]
    }, ...]
}

解决方案

使用模版列

第一个解决方案是使用模版列。模版列可以轻松的在单元格内显示Ext JS模版。
在当前情况下,使用HTML模版来显示这些图标相当的简单,而且可避免action列丢失配置项带来的麻烦:

{
    xtype: 'grid',
    columns: [{
        xtype: 'templatecolumn',
        items: [{
            xtype: 'button',
            iconCls: 'x-fa fa-plus',
            ui: 'default-toolbar'
        }],
        tpl: '<span class="x-fa fa-pencil"></span><span class="x-fa fa-trash"></span>'
    }]
}

不过,在每个图标上独立去处理他们的单击操作、启用或禁用操作以及提示信息,这将是比较痛苦的事情。
对于action列,是通过isActionDiasbled、handler或getTip方法来处理交互的。要在模版列实现这个,需要手动编写这些代码。

为action列创建插件

第二个解决方案是为action列创建一个插件,这更证据且更模块化。这插件的作用就是提供一种方式来配置列标题中的按钮,这样,既保留了action列的所有功能,又能获得所需的效果。

如何创建一个插件

一个扩展自Ext.AbstractPlugin的Ext JS类:

Ext.define('MyApp.plugin.ActionColumnHeaderButtonPlugin', {
    extend: 'Ext.AbstractPlugin',
    alias: 'plugin.actioncolumnheaderbuttonplugin',
    actionColumnHeaderId: null,
    config: {
        buttonConfig: null
    }

定义别名是为了能方便的在列中识别插件。
在这里定义了一个属性来定位列标题内的按钮的容器。
最后,创建了一个按钮配置项来定义列标题内的按钮。

初始化

对于任何插件,可通过重写抽象方法init来获取组件并与组件实现交互。
可以通过调用set方法将插件与组件连接上:

this.setCmp(cmp);

然后,监听grid的viewready时间(在后面会讲述事件触发时会发生什么事情):

var ownerGrid = cmp.getView().ownerGrid;
ownerGrid.on('viewready', this.onViewReady, this);

然后针对列的id创建一个唯一的标识:

this.actionColumnHeaderId = cmp.getId() + '-actioncolumnheaderCt';

最后,在列标题内注入一个带有之前创建的唯一标识的HTML块,这样,就可以很容易的在插件的公共方法中来访问它。

cmp.setText('<div id="' + this.actionColumnHeaderId + '"></div>');

以下是最终完成的init方法:

init: function (cmp) {
    this.setCmp(cmp);
    var ownerGrid = cmp.getView().ownerGrid;
    ownerGrid.on('viewready', this.onViewReady, this);
    this.actionColumnHeaderId = cmp.getId() + '-actioncolumnheaderCt';
    cmp.setText('<div id="' + this.actionColumnHeaderId + '"></div>');
}
在grid创建时添加按钮

Grid渲染完以后,就会触发viewready时间,就是插件监听的那个事件。当事件触发事,就可通过buttonConfig的设置来创建按钮:

var button = Ext.create('Ext.button.Button', this.getButtonConfig());

然后将这个组件注入到插件初始化时添加的容器内:

button.render(view.el.down('#' + this.actionColumnHeaderId));

完整的onViewReady方法代码如下:

onViewReady: function (view) {
    var button = Ext.create('Ext.button.Button',  this.getButtonConfig());
    button.render(view.el.down('#' + this.actionColumnHeaderId));
}
在列中设置插件:
columns: [{
    xtype: 'actioncolumn',
    plugins: [{
        ptype: 'actioncolumnheaderbuttonplugin',
        buttonConfig: {
            iconCls: 'x-fa fa-plus',
            handler: 'onAddButtonClick'
        }
    }],
    items: [{
        iconCls: 'x-fa fa-pencil'
    }, {
        iconCls: 'x-fa fa-trash'
    }]
}]

这样,就可以既使用action列的既有功能,又可以在列标题内设置一个按钮。

访问这里可以获取完整的代码以及它的结果。

展开阅读全文

没有更多推荐了,返回首页