分享

ExtJs4之gridPanel

 旭龙 2013-01-31

大家好,继上次的treepanel之后,今天给大家介绍gridpanel,gridpanel也是在extjs编程中出现频率高的一种组件,是必须要掌握的,当然,gridpanel比treepanel要复杂的多,基本上能实现excel中大部分基本功能,功能相当强大。

 

先上张截图吧,一睹grid的芳容(这是未经过处理的最基本的grid界面)

 

 

 

grid的实现包括model、store和view三个层面。

 

从model开始,先贴代码再讲解:

 

 

Js代码  收藏代码
  1. Ext.define('eduSys.Course.model', {  
  2.     extend : 'Ext.data.Model',  
  3.  // idProperty : 'name',  
  4.     fields : [  
  5.         {name : 'coursesGuid', type : 'string'},  
  6.         {name : 'code', type : 'string'},  
  7.         {name : 'name', type : 'string'},  
  8.         {name : 'period', type : 'int'}           
  9.     ]  
  10.  });  

 

代码的一开始,先定义一个model类,名字自己取,然后就是model里的键值对属性赋值,首先最重要的就是这个自定义的类要继承自Ext.data.Model,用extend属性来表示,再就是这个表格的基本属性,即表格每一列代表的含义,用field属性来表示,field是一个数组类型,里面存放各个列属性对象,每个对象里面要定义对象的名字(name)和类型(type),便于与后面的store层进行连接。至于idProperty(可有可无)这个属性后面讲解。这样model就基本写好了,很简单吧。

 

下面store层,代码如下:

 

Js代码  收藏代码
  1.  Ext.define('eduSys.KnowledgeCourse.store', {  
  2.   
  3.     extend : 'Ext.data.Store',  
  4.     model : 'eduSys.Course.model',  
  5.     storeId : 'knowledgeCourseStore',  
  6.     pageSize : 5,  
  7.       
  8.     proxy : {  
  9.         type : 'ajax',  
  10.         url : '../../KnowledgeUnitServlet',  
  11.         extraParams: {  
  12.             guid : document.location.search.split('=')[1],  
  13.             cmd : 'getCourses'  
  14.         },  
  15.         reader : {  
  16.             type : 'json'  
  17.         }  
  18.     },  
  19. /*  sorters : [{ 
  20.             property : 'name', 
  21.             direction : 'ASC' 
  22.     }],*/  
  23.     autoLoad : {start : 0, limit : 5}   
  24. });  

 

 store层也是自定义一个类,继承自Ext.data.Store,然后这里也是定义model,就是前面写的model层,model的赋值即前面写的model层的名称,然后最主要的是proxy,定义从后台去取数据,然后加载到grid 中,proxy中url好说,extraParams添加额外的参数传到后台,已json的形式读取数据。store中的autoload属性也需要赋值,代表程序什么时候像后台发送请求加载数据,可以赋boolean/Object,默认的是false,默认不发送请求,但可以在程序中可以通过grid的)函数拿到store对象然后调用load函数,然后系统就会像后台发送定义的proxy里的内容并加载,若手动设置为true,表示一开始就请求数据。上面代码赋值的是一个对象,用于分页用的。

当然,store也可以装载已经定义好的数据集,设置store的data属性,里面存放对象数组,键值对与model相对应,则表格自动填充这些数据,如下:

 

Java代码  收藏代码
  1. data : [  
  2.         {code : 'OS1', name : '万俟辉夜1', period : 32},  
  3.         {code : 'OS2', name : '万俟辉夜2', period : 48},  
  4.         {code : 'OS3', name : '万俟辉夜3', period : 60},  
  5.     ],  
 

 

最后就是view层的代码实现了:

 

Java代码  收藏代码
  1. Ext.define('eduSys.KnowledgeCourse.grid', {  
  2.       
  3.     extend : 'Ext.grid.Panel',  //继承自Ext.grid.Panel  
  4.     alias : 'widget.knowledgeCourseGrid',  //取别名knowledgeCourseGrid  
  5.     title : '课程',  //表格标题  
  6.     frame : true,//窗口化,即让界面变的饱满  
  7.     selType : 'cellmodel',//设置单元格选中方式,默认为rowmodel,行选择  
  8.     enableKeyNav : true,//允许键盘操作,即上下左右移动选中点  
  9.     forceFit : true,//自动填充,即让所有列填充满gird宽度  
  10.     config : [  //预先配置  
  11.         GridDoActionUtil = Ext.create('Ext.Util.GridDoActionUtil'),  //操作util类,这里可不管  
  12.         myStore = new eduSys.KnowledgeCourse.store()  //定义grid的store,即前面定义的store  
  13.     ],  
  14.     columns : [ //关键部分,定义每一列的属性  
  15.         {  
  16.             text : '编号',                 //定义该列的标题名称  
  17.             dataIndex : 'code',     //对应model中的列属性  
  18.             align : 'center',           //居中显示  
  19.             editor : {xtype : 'textfield'}   //定义该列可以编辑,编辑框形式  
  20.         },   
  21.         {  
  22.             text : '名称',  
  23.             dataIndex : 'name',  
  24.             align : 'center'  
  25.         },  
  26.         {  
  27.             text : '学时',  
  28.             dataIndex : 'period',  
  29.             align : 'center'  
  30.         },  
  31.         {                 //这一列大家看看就行了,是actioncolumn相关操作  
  32.             xtype : 'actioncolumn',  
  33.             align : 'center',  
  34.             html : '<div style="margin-top: 4px;">详情</div>',  
  35.             items: [{  
  36.                 icon : '../../images/view.png',  
  37.                 handler:   
  38.                     this.GridDoActionUtil.doDetail  
  39.             }]  
  40.         }  
  41.     ],  
  42.     tbar : [     //定义工具栏,上面可以存放各种组件  
  43.         {  
  44.             xtype : 'combobox',      //放一个combobox,用法以后再介绍  
  45.             id : 'courseCombo',  
  46.             store : new eduSys.Course.comboStore(),  
  47.             queryMode : 'remot',  
  48.             valueField : 'coursesGuid',  
  49.             displayField : 'name',  
  50.             editable : false  
  51.         },  
  52.         {xtype : 'button', text : '增加', iconCls : 'edu_add',     
  53.             handler : function(btnObj) {  
  54.                 //dosomething();      
  55.             }  
  56.         }, // 放一个button按钮,定义它的样式(iconCls),点击响应方式(handler)  
  57.         {xtype : 'button', text : '删除', iconCls : 'edu_remove',  
  58.             handler :   
  59.                 this.GridDoActionUtil.doRemove  
  60.         }  
  61.     ],  
  62.     bbar : {    //定义底部工具栏  
  63.         xtype : 'pagingtoolbar',   //分页工具条  
  64.         store : this.myStore,     //数据集跟grid的数据集一样  
  65.         displayInfo : true          //是否显示数据集信息  
  66.     },  
  67.       
  68.     selType : 'checkboxmodel',  //设置前面有多选框选项  
  69.     multiSelect : true,    //可以多选  
  70.     store : this.myStore        //定义grid的store,即前面写的store  
  71. });  
 

 

view层的信息量就比较大了,所以基本信息都在代码里添加注释,应该看的还比较清楚,有的属性有不同的配置,大家可以在官网api上查找该属性,上面有详细的解释,鉴于上面代码已经可以代表大部分的需求,这里就不在多说。

 

好了,上面代码基本上能实现大部分对于表格的要求了,另外gird还有其他增强功能,比如拖拽、分组等等,每一列还有很多其他的属性进行设置,比如常见的render(渲染)、format(格式化)等等,今天由于时间原因就不写了,以后要是有时间再写一篇gird的增强篇,在这里像大家致歉。

 

 

贴一下grid的增加、删除、保存行的操作代码,比较简单。

 

Java代码  收藏代码
  1. doAdd : function(grid, modelObj) {  
  2.         if(!(grid && modelObj)) {  
  3.             Ext.Msg.alert('error','参数传递不正确!!!');  
  4.             return;  
  5.         }  
  6.         var store = grid.getStore();  
  7.         //得到目前表格的数据集合的长度  
  8.         var storeCount = store.getCount();  
  9.         //得到编辑插件  
  10.         var edit = grid.editingPlugin;  
  11.         //得到数据模型  
  12.         var model = store.model;  
  13.           
  14.         var eduObj = new model(modelObj);  
  15.         store.insert(storeCount,eduObj);  
  16.     },  
  17.       
  18.     doRemove : function(grid) {  
  19.         var data = grid.getSelectionModel().getSelection();  
  20.         if(data.length == 0) {  
  21.             MsgTip.msg("提示","请选中项删除!!!",true);  
  22.         } else {  
  23.             var st = grid.getStore();  
  24.             Ext.Array.each(data, function(record) {  
  25.                 st.remove(record);  
  26.             });  
  27.         }  
  28.     },  
  29.       
  30.     doSave : function(grid) {  
  31.         if(!grid) {  
  32.             Ext.Msg.alert('参数传递不正确!!!');  
  33.             return;   
  34.         }  
  35.         //得到数据集合  
  36.         var store = grid.getStore();  
  37.         //records 被你修改过的数据  
  38.         var records = store.getUpdatedRecords();  
  39.         var data = [];  
  40.         Ext.Array.each(records, function(model) {  
  41.             data.push(model.data);  
  42.         });  
  43.         if(data.length > 0) {  
  44.             Ext.Ajax.request({     //ajax后台传输数据  
  45.                 url : '要传的url',  
  46.                 params : {data : "[" +data.join(',')+ "]"},  
  47.                 method : 'POST',  
  48.                 timeout : 4000,  
  49.                 success : function(response,opts) {  
  50.                     //dosomething();  
  51.                     //取消小箭头  
  52.                     model.commit();   
  53.                 }  
  54.             });  
  55.         }  
  56.     },  

 

下面说一下大家普遍遇到的grid保存中store.getUpdatedRecords();拿到数据为空的问题,我也是在上面纠结了一段时间,觉得有必要在这把解决方案提出来。

 

grid的model层有一个属性:idProperty ,默认是id,这个属性就是grid所有列的主属性,相当于数据库中的主键定义,是不可缺少的,所以当你的model中配置没有id基本字段的时候,extjs内部的函数如getUpdatedRecords();就拿不到行的句柄(就用大家都懂的句柄这个词吧),所以取出来的值为空,解决方案就是配置idProperty为你定义的字段中一个,这样就解决了。

可是,有的兄台可能碰到跟我一样的问题,我的表格是可以新添加行的,用store的Number index, Ext.data.Model[] records )函数添加新的一行,这个添加的model中每个属性都是空,但是,idProperty也配置了,结果拿出来的东西还是为空,我就纳闷了,怎么还是行不通,最后经过慢慢对比调试,终于发现了根本问题,在新增的一行中idProperty设置的属性必须要赋值,就像主键不能为空一样,经过赋值后的model对象插入到gird中后再调用getUpdatedRecords(); 就没有问题了,能正常拿出更改的值。

 

 

最后说一下grid的分页组建的实现细节。

在store层的定义中就定义了pageSize表示每一页的行数,autoLoad中定义一个对象(如上面store中的autoLoader),上面表示最开始的起始位置和请求个数,这样在往后台请求的URL中就增加了两个请求参数start和limit,按上面代码就是添加了start=0&limit=5,这样后台就可以接受参数进行处理,那么上一页下一页又是怎么处理的呢,在bbar中定义了分页组建,当点击下一页的按钮时,extjs会自动像后台发送一个URL请求,与proxy是同一个url请求,同样的会添加两个请求参数start和limit,只是这时的start值就是当前的值加上(下一页)或者减去(上一页)pageSize大小,在后台进行处理就行了。

 

 

最后的最后,本文如果写的有什么不足,希望大家与我交流,共同学习,共同进步。。。。。。。。。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多