ExtJS扩展:扩展grid

ExtJs的grid功能很强大,可是有时候以为老是少那么一点点功能微笑,咱们就来扩展它,让它用起来更方便。css

今天咱们要扩展的是:根据记录的选择数量来禁用或启用grid toolbar上的某些按钮git

本文全部的代码和例子都在个人github上:ExtJsExtendgithub

开始以前

在开始以前,咱们先来扩展ExtJs的container容器。数组

在ExtJs中,能够经过给组件分配一个id来标识它,id是一个全局的惟一的标识,而后经过Ext.getCmp(id)来获取这个组件,看起来很方便,可是在单页应用中,给组件一个惟一的全局id名是很伤脑筋的事情。ExtJs也考虑到了这种状况,就弄了一个itemId,这个不须要全局惟一,只要在同一个container中惟一就能够了,而且也提供了一个方法经过itemId获取组件:container.getComponent(itemId),其实这个方法的参数不单单是支持itemId,也能够传入全局惟一的id或者组件在container中的位置来获取该组件。app

可是对于咱们来讲,仍是有那么一点点不方便,好比在一个form中,有fieldContainer或者fieldSet,经过form.getComponet(),只能获取form的直接child,不能获取到form中嵌套的container下的child,这样只能经过form先找到嵌套的container,而后再调用该container的getComponet方法获取到须要的组件,这在一个复杂布局的form中(好比在fieldSet中又嵌套fieldContainer)操做起来就更加不方便了。ide

等等,container不是有一个items属性吗?这里是否能够获取到跨级的组件呢?很遗憾,这个items集合也只是包含了直接的child。布局

咱们的解决方案就是allItems,从名称上就能看出来,allItems就是包含就是包含全部直接或嵌套(不限层级)的child(其实也不是全部的child,后面的代码中能够看到)。flex

实现方法很简单:给container一个allItems的属性,而后重载container的onAdd和onAdded方法,注意这两个的区别,onAdd是有组件加入到这个容器中的时候被调用,onAdded是本身(container本身首先也是一个组件)被加入到某个container的时候被调用,代码很简单,直接贴出代码: this

Ext.define('Ext.container.ContainerOverride', { 
    override: 'Ext.container.Container', 
    initComponent: function () { 
        var me = this; 
        Ext.applyIf(me, { 
            allItems: {}, 
            preventItemsBubble: true 
        }); 
        me.callParent(); 
    }, 
    onAdd: function (cmp) { 
        var me = this; 
        me.callParent(arguments); 
        var name = cmp.itemId || cmp.name; 
        if (name) { 
            if (me.allItems[name]) { 
                me.allItems[name] = Ext.Array.merge( 
                    Ext.Array.from(me.allItems[name]), 
                    [cmp]); 
            } 
            else { 
                me.allItems[name] = cmp; 
            } 
        } 
    }, 
    onAdded: function (container) { 
        var me = this; 
        me.callParent(arguments); 
        if (container && me.preventItemsBubble !== true) { 
            for (var name in me.allItems) { 
                if (container.allItems[name]) { 
                    container.allItems[name] = Ext.Array.merge( 
                        Ext.Array.from(container.allItems[name]), 
                        Ext.Array.from(me.allItems[name])); 
                } 
                else { 
                    container.allItems[name] = me.allItems[name]; 
                } 
            } 
        } 
    } 
}); 
 
 

须要说明的是:spa

  1. 1. allItems是一个object,不是一个数组,经过组件的itemId或name(由于在form中field大多都有name,这样就不须要定义itemId了)来索引,itemId优先 。(嗯,以前说了其实并非ALL)
  2. 2. itemId不在同一个container中能够重复,name能够在同一个container重复,若是有重复的itemId或name,那么allItems[itemId]获取到的将是一个数组
  3. 3. preventItemsBubble属性是为了阻止将allItems向上级冒泡,好比在一个form中,只要form可以获取到allItems就能够了,form的上级就没有必要知道这些items了,默认是阻止的,因此要在form的fieldContainer等中将其设置成false,fieldContainer等中的allItems才能冒泡到form的allItems中

扩展grid之toolbar的按钮

先上一组效果图:

image

当没有记录被选中的时候Edit和Delete按钮都是disabled的。

 

image

当有一条记录被选中的时候,Edit和Delete都启用了。

 

image

当有2条或以上的记录被选中的时候,Edit被禁用了(由于设计的时候要求只能同时编辑一条记录)。

在前面的效果图中看到New始终是可使用的,由于新建和选不选中记录都没有关系。

 

其实这个效果实现起来很简单,无非就是监听selectionchange事件,而后根据选中的记录数来disable掉对应的按钮便可,可是若是有不少grid都要这样作是否是就变成了拷贝粘贴而后修改代码,天然咱们就想到了重用,先看看咱们这个例子的代码:

            Ext.create('Ext.grid.Panel', { 
                title: 'Simpsons', 
                store: Ext.data.StoreManager.lookup('simpsonsStore'), 
                noSelectionDisable:['Edit','Delete','Print'], 
                moreSelectionsDisable:['Edit'], 
                selModel: Ext.create('Ext.selection.CheckboxModel', { allowDeselect: true }), 
                tbar: { 
                    xtype: 'toolbar', 
                    preventItemsBubble: false, 
                    items: [ 
                        { 
                            xtype: 'button', 
                            itemId: 'Edit', 
                            text: 'Edit'}, 
                        { 
                            xtype: 'button', 
                            name: 'Delete', 
                            text: 'Delete'} 
                    ]}, 
                dockedItems: [ 
                    { 
                        xtype: 'toolbar', 
                        preventItemsBubble: false, 
                        dock: 'right', 
                        items: [ 
                            { 
                                xtype: 'button', 
                                name: 'New', 
                                text: 'New'}, 
                            { 
                                xtype: 'button', 
                                itemId: 'Edit', 
                                text: 'Edit'}] 
                    } 
                ], 
                columns: [ 
                    { text: 'Name', dataIndex: 'name' }, 
                    { text: 'Email', dataIndex: 'email', flex: 1 }, 
                    { text: 'Phone', dataIndex: 'phone' } 
                ], 
                height: 200, 
                width: 400, 
                renderTo: Ext.getBody() 
            }); 

代码中能够看到有2个配置参数是ExtJs grid中没有,这就是咱们扩展的:

 

noSelectionDisable:['Edit','Delete','Print'],

moreSelectionsDisable:['Edit'],

 

noSelectionDisable就是告诉grid若是没有记录被选中,那就禁用这些名称(itemId)的按钮。

moreSelectionsDisable就是告诉grid若是有超过2条的记录被选中,那么就禁用这些名称(itemId)的按钮。

在源代码中找找,这些name在哪里?对,就是tbar和dockedItems中定义的button的名称(itemId)。这样使用grid是否是很简单了?

 

这就是grid的扩展代码:

Ext.define('Ext.ux.grid.PanelOverride', { 
    override: 'Ext.grid.Panel', 
    initComponent: function () { 
        var me = this; 
        me.on('selectionchange', me.onSelectionChange, me); 
        me.callParent(); 
    }, 
    onSelectionChange: function (grid, records) { 
        if (!records) { 
            return; 
        } 
        var me = this; 
        var items = me.allItems; 
        var disableNames = me.noSelectionDisable; 
        if (records.length == 1) { 
            disableNames = me.oneSelectionDisable; 
        } 
        if (records.length > 1) { 
            disableNames = me.moreSelectionsDisable; 
        } 
        for (var name in items) { 
            var item = items[name]; 
            if (Ext.isArray(item)) { 
                Ext.Array.each(item, function (oneItem) { 
                    if (oneItem.enable) { 
                        oneItem.enable(); 
                    } 
                }); 
            } 
            else if (item.enable) { 
                item.enable(); 
            } 
            if (disableNames && Ext.Array.contains(disableNames, name)) { 
                if (Ext.isArray(item)) { 
                    Ext.Array.each(item, function (oneItem) { 
                        if (oneItem.disable) { 
                            oneItem.disable(); 
                        } 
                    }); 
                } 
                else if (item.disable) { 
                    item.disable(); 
                } 
            } 
        } 
    } 
}); 

在代码中能够看到,正是利用了以前扩展的allItems,因此能方便地得到grid toolbar中的按钮,使得代码很是精简了。

但愿能对使用ExtJs的朋友有帮助,谢谢。

 

全部代码和例子在个人github上:ExtJsExtend

相关文章
相关标签/搜索