Ext2.0框架的Grid使用介绍     
            最近空闲时间在学习Ext2.0框架,只有一个字的感叹“强”,我从未想到JS代码能够写出这么绚丽的Web页面出来,以前看到YUI,惊若天人,如今看到EXT2.0的东西,更是感觉震撼。
            Ext2.0是一个JS框架,它的Grid控件和其它可以显示数据的控件,能够支持多种数据类型,如二维数组、Json数据和XML数据,甚至包括我们自定义的数据类型。Ext为我们提供了一个桥梁Ext.data.Store,通过它我们可以把任何格式的数据转化成grid可以使用的形式,这样就不需要为每种数据格式写一个grid的实现了。
            首先,一个表格应该有列定义,即定义表头ColumnModel:
            // 定义一个ColumnModel,表头中有四列
            var cm = new Ext.grid.ColumnModel([
                {header:'编号',dataIndex:'id'},
                {header:'性别',dataIndex:'sex'},
                {header:'名称',dataIndex:'name'},
                {header:'描述',dataIndex:'descn'}
            ]);
            cm.defaultSortable = true;
                该ColumnModel定义了表格的四个列,其每列的名称和对应的数据键。请注意defaultSortable属性,即为每个列都安上一个可以排序的功能。如果只想某些列举有该功能,可以设置:
            {header:'编号',dataIndex:'id',Sortable:true},
            现在就来看看这个Ext.data.Store是如何转换三种数据的。
            1.二维数组:
            // ArrayData
            var data = [
                ['1','male','name1','descn1'],
                ['2','male','name1','descn2'],
                ['3','male','name3','descn3'],
                ['4','male','name4','descn4'],
                ['5','male','name5','descn5']
            ];
            // ArrayReader
            var ds = new Ext.data.Store({
                proxy: new Ext.data.MemoryProxy(data),
                reader: new Ext.data.ArrayReader({}, [
                    {name: 'id',mapping: 0},
                    {name: 'sex',mapping: 1},
                    {name: 'name',mapping: 2},
                    {name: 'descn',mapping: 3}
                ])
            });
            ds.load();
            ds要对应两个部分:proxy和reader。proxy告诉我们从哪里获得数据,reader告诉我们如何解析这个数据。
            现在用的是Ext.data.MemoryProxy,它将内存中的数据data作为参数传递。Ext.data.ArrayReader专门用来解析数组,并且告诉我们它会按照定义的规范进行解析,每行按顺序读取四个数据,第一个叫id,第二个叫sex,第三个叫name,第四个descn。这些是跟cm定义中的dataIndex对应的。这样cm就知道哪列应该显示那条数据了。
            mapping属性用于标记data中的读取后的数据与标头的映射关系,一般是不用设置的。但如果我们想让sex的数据中name栏中出现,可以设置mapping值。即id的mapping为2,后者为0。
            记得要执行一次ds.load(),对数据进行初始化。
            数据的显示显得非常简单:
            HTML文件:
            <div id='grid'></div>
            JS文件:
            var grid = new Ext.grid.GridPanel({
                el: 'grid',
                ds: ds,
                cm: cm
            });
            grid.render();
            其显示结果为:
            
            2.如何在表格中添加CheckBox呢?
            var sm = new Ext.grid.CheckboxSelectionModel();
            var cm = new Ext.grid.ColumnModel([
                new Ext.grid.RowNumberer(),//自动行号
                sm,//添加的地方
                {header:'编号',dataIndex:'id'},
                {header:'性别',dataIndex:'sex'},
                {header:'名称',dataIndex:'name'},
                {header:'描述',dataIndex:'descn'}
            ]);
            var grid = new Ext.grid.GridPanel({
                el: 'grid3',
                ds: ds,
                cm: cm,
                sm: sm,//添加的地方
                title: 'HelloWorld'
            });
            
            3. 如何做Grid上触发事件呢?
            下面是一个cellclick事件
            grid.addListener('cellclick', cellclick);
            function cellclick(grid, rowIndex, columnIndex, e) {
                var record = grid.getStore().getAt(rowIndex);   //Get the Record
                var fieldName = grid.getColumnModel().getDataIndex(columnIndex); //Get field name
                var data = record.get(fieldName);
                Ext.MessageBox.alert('show','当前选中的数据是'+data);
            }
            4.如何做Grid中做出快捷菜单效果:
            grid.addListener('rowcontextmenu', rightClickFn);//右键菜单代码关键部分
            var rightClick = new Ext.menu.Menu({
                id:'rightClickCont', //在HTML文件中必须有个rightClickCont的DIV元素
                items: [
                    {
                        id: 'rMenu1',
                        handler: rMenu1Fn,//点击后触发的事件
                        text: '右键菜单1'
                    },
                    {
                        //id: 'rMenu2',
                        //handler: rMenu2Fn,
                        text: '右键菜单2'
                    }
                ]
            });
            function rightClickFn(grid,rowindex,e){
                e.preventDefault();
                rightClick.showAt(e.getXY());
            }
            function rMenu1Fn(){
               Ext.MessageBox.alert('right','rightClick');
            }
            其Grid如下:
            
            5.如何将一列中的数据根据要求进行改变呢?
            比如说性别字段根据其male或female改变显示的颜色,这种ColumnMode中设计:
            var cm = new Ext.grid.ColumnModel([
                new Ext.grid.RowNumberer(),
                sm,
                {header:'编号',dataIndex:'id'},
                {header:'性别',dataIndex:'sex',renderer:changeSex},
                {header:'名称',dataIndex:'name'},
                {header:'描述',dataIndex:'descn'}
            ]);
            cm.defaultSortable = true;
            function changeSex(value){
                if (value == 'male') {
                    return "<span style='color:red;font-weight:bold;'>红男</span>";
                } else {
                    return "<span style='color:green;font-weight:bold;'>绿女</span>";
                }
            }
            其它两种数据的Grid显示是相同的,其不同之处在于数据获取的过程:
            6.Json数据
            至于这种数据的类型请大家自己看Ajax的书籍:
            //JsonData
            var data = { 
                'coders': [
                    { 'id': '1', 'sex': 'male', 'name':'McLaughlin', 'descn': 'brett@newInstance.com' },
                    { 'id': '2', 'sex': 'male','name':'Hunter', 'descn': 'jason@servlets.com' },
                    { 'id': '3', 'sex': 'female','name':'Harold', 'descn': 'elharo@macfaq.com' },
                    { 'id': '4', 'sex': 'male','name':'Harolds', 'descn': 'elhaross@macfaq.com' }
                ],
                'musicians': [
                    { 'id': '1', 'name': 'Clapton', 'descn': 'guitar' },
                    { 'id': '2', 'name': 'Rachmaninoff', 'descn': 'piano' }
                ]
            }
            //ds使用的MemoryProxy对象和JsonReader对象
            var ds = new Ext.data.Store({
                    proxy: new Ext.data.MemoryProxy(data),
                    reader: new Ext.data.JsonReader({root: 'coders'}, [
                        {name: 'id'},
                        {name: 'sex'},
                        {name: 'name'},
                        {name: 'descn'}
                    ])
                });
            ds.load();
            var grid = new Ext.grid.GridPanel({
                el: 'grid3',
                ds: ds,
                cm: cm,
                sm: sm,
                title: 'HelloWorld',
                autoHeight: true//一定要写,否则显示的数据会少一行
            });
            grid.render();
            
            7.使用XML数据:
            注意,读取XML数据必须在服务器上进行。
            XML数据test.xml的内容:
            <?xml version="1.0" encoding="UTF-8"?>
            <dataset>
                 <results>2</results>
                 <item>
                       <id>1</id>
                       <sex>male</sex>
                       <name>Taylor</name>
                       <descn>Coder</descn>
                 </item>
            </dataset>var ds3 = new Ext.data.Store({
                url: 'test.xml',   //XML数据
                reader: new Ext.data.XmlReader({record: 'item'}, [ //使用XmlReader对象
                    {name: 'id'},
                    {name: 'sex'},
                    {name: 'name'},
                    {name: 'descn'}
                ])
            });
            
            8.从服务器获取数据和数据翻页控件
            从一个服务器文件,如ASP、JSP或Servlet中获得数据二维Array、JSON或XML数据,也可以被Ext读取,并被Grid显示:
            服务器文件data.asp:
            <%
                start = cint(request("start"))
                limit = cint(request("limit"))
                dim json
                json=cstr("{totalProperty:100,root:[")
                
                for i = start to limit + start-1
                    json =json + cstr("{'id':'") +cstr(i) + cstr("','name':'name") + cstr(i) + cstr("','descn':'descn") + cstr(i) + cstr("'}")
                    if i <> limit + start - 1 then
                        json =json + ","
                    end if
                next
                json = json +"]}"
                response.write(json)
            %>
            我们可以看到,这个页面会根据传入的start和limit的不同,返回不同的数据,其实质是个分页的代码。下面是start=0,limit=10的JSON数据:
            {totalProperty:100,root:[{'id':'0','name':'name0','descn':'descn0'},{'id':'1','name':'name1','descn':'descn1'},{'id':'2','name':'name2','descn':'descn2'},{'id':'3','name':'name3','descn':'descn3'},{'id':'4','name':'name4','descn':'descn4'},{'id':'5','name':'name5','descn':'descn5'},{'id':'6','name':'name6','descn':'descn6'},{'id':'7','name':'name7','descn':'descn7'},{'id':'8','name':'name8','descn':'descn8'},{'id':'9','name':'name9','descn':'descn9'}]}
            我们使用分页控件来控制Grid的数据:
            Ext.onReady(function(){
                var sm = new Ext.grid.CheckboxSelectionModel();
                
                var cm = new Ext.grid.ColumnModel([
                    new Ext.grid.RowNumberer(),
                    sm,
                    {header:'编号',dataIndex:'id'},
                    {header:'性别',dataIndex:'sex'},
                    {header:'名称',dataIndex:'name'},
                    {header:'描述',dataIndex:'descn'}
                ]);
                cm.defaultSortable = true;
                var ds = new Ext.data.Store({
                    proxy: new Ext.data.HttpProxy({url:'data.asp'}),
                    reader: new Ext.data.JsonReader({
                        totalProperty: 'totalProperty',
                        root: 'root'
                    }, [
                        {name: 'id'},
                        {name: 'name'},
                        {name: 'descn'}
                    ])
                });
                ds.load({params:{start:0,limit:10}});
                
                var grid = new Ext.grid.GridPanel({
                    el: 'grid3',
                    ds: ds,
                    cm: cm,
                    sm: sm,
                    title: 'ASP->JSON',
                    bbar: new Ext.PagingToolbar({
                        pageSize: 10,
                        store: ds,
                        displayInfo: true,
                        displayMsg: '显示第 {0} 条到 {1} 条记录,一共 {2} 条',
                        emptyMsg: "没有记录"
                    }),
                    tbar: new Ext.PagingToolbar({
                        pageSize: 10,
                        store: ds,
                        displayInfo: true,
                        displayMsg: '显示第 {0} 条到 {1} 条记录,一共 {2} 条',
                        emptyMsg: "没有记录"
                    })
                });
                grid.render();
            })
            
            10.如何在Grid的上方添加按钮呢?
            添加按钮的关键之处在于tbar或bbar属性设置Toolbar工具条:
            var grid = new Ext.grid.GridPanel({
                el: 'grid3',
                ds: ds,
                cm: cm,
                sm: sm,
                title: 'HelloWorld',
                tbar: new Ext.Toolbar({ 
                    items:[ 
                            { 
                                id:'buttonA' 
                                ,text:"Button A" 
                                ,handler: function(){ alert("You clicked Button A"); } 
                            } 
                            ,
                            new Ext.Toolbar.SplitButton({})
                            ,{ 
                                id:'buttonB' 
                                ,text:"Button B" 
                                ,handler: function(){ alert("You clicked Button B"); } 
                            } 
                            ,
                            '-'
                            ,{
                                id:'buttonc' 
                                ,text:"Button c"
                            }
                        ] 
                    }) 
            });
            
            
            11.将GridPanel放入一个Panel或TabPanel中
            var tabs = new Ext.TabPanel({
                collapsible: true
                ,renderTo: 'product-exceptions'
                ,width: 450
                ,height:400
                ,activeTab: 0
                ,items:[
                    {
                        title: 'Unmatched'
                    },{
                        title: 'Matched'
                    }
                ]
            });
            tabs.doLayout();
            var panel = new Ext.Panel({
                renderTo: 'panel',
                title:'panel',
                collapsible:true,
                width:450,
                height:400,
                items:[grid] //管理grid
            });
            Panel必须有DIV存在。其包含的Component有items管理。
            
            本文是在学习Ext2.0的基础上写的,因此,参考了许多网上存在的Blog文章。在此表示致敬!