惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
I
InfoQ
宝玉的分享
宝玉的分享
Blog — PlanetScale
Blog — PlanetScale
博客园 - 司徒正美
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
P
Privacy International News Feed
T
Threatpost
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
V
Vulnerabilities – Threatpost
NISL@THU
NISL@THU
aimingoo的专栏
aimingoo的专栏
S
Schneier on Security
C
Cisco Blogs
T
The Blog of Author Tim Ferriss
Simon Willison's Weblog
Simon Willison's Weblog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Jina AI
Jina AI
雷峰网
雷峰网
Know Your Adversary
Know Your Adversary
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
I
Intezer
博客园 - Franky
博客园 - 【当耐特】
Hugging Face - Blog
Hugging Face - Blog
The Hacker News
The Hacker News
K
Kaspersky official blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
T
Tailwind CSS Blog
Project Zero
Project Zero
T
Tor Project blog
B
Blog RSS Feed
Recorded Future
Recorded Future
Scott Helme
Scott Helme
美团技术团队
V
V2EX
V
Visual Studio Blog
L
Lohrmann on Cybersecurity
P
Proofpoint News Feed
D
DataBreaches.Net
The Register - Security
The Register - Security
M
MIT News - Artificial intelligence
L
LangChain Blog
Cisco Talos Blog
Cisco Talos Blog
博客园 - 三生石上(FineUI控件)
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
C
Cyber Attacks, Cyber Crime and Cyber Security
博客园_首页
P
Privacy & Cybersecurity Law Blog

博客园 - tubo

依赖Asp.net Core的类库 找一款可以插入数学公式的思维导图软件 联想个人云开启Docker并安装常用的Docker 联想个人云无损开启SSH 我只想在Windows Server 2019上build 基于Linux的Docker Gerrit 添加用户 Windows 10 安装过程中,在自定义登录页面进入审核模式 mac远程桌面连接windows 8.1 update,提示: 远程桌面连接无法验证您希望连接的计算机的身份 iOS开发点滴:iPhone屏幕适配 C# Winform中如何让PictureBox的背景透明 ExtJS扩展:扩展grid之toolbar button禁用表达式 Extjs扩展:封装Plupload 用NuGet管理程序包时,如果解决方案目录下的packages文件夹中某一个程序包存在2个以上的版本,则会提示错误 User Profile Service服务未登录,无法加载用户配置文件 可动态构造查询条件的表达式类库(1) Windows 8安装杀毒软件avast后,不能用Sysprep进行通用化封装 Nuget 启用数据库迁移的时候一定要把包含DbContext的项目设为启动项目 “PostSharp21”任务意外失败 为什么TFS会自动签出解决方案文件(.sln)?
ExtJS扩展:扩展grid
tubo · 2013-11-11 · via 博客园 - tubo

ExtJs的grid功能很强大,但是有时候觉得总是少那么一点点功能微笑,我们就来扩展它,让它用起来更方便。

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

本文所有的代码和例子都在我的github上:ExtJsExtend

开始之前

在开始之前,我们先来扩展ExtJs的container容器。

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

但是对于我们来说,还是有那么一点点不方便,比如在一个form中,有fieldContainer或者fieldSet,通过form.getComponet(),只能获取form的直接child,不能获取到form中嵌套的container下的child,这样只能通过form先找到嵌套的container,然后再调用该container的getComponet方法获取到需要的组件,这在一个复杂布局的form中(比如在fieldSet中又嵌套fieldContainer)操作起来就更加不方便了。

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

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

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

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

需要说明的是:

  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