上次发了Easyui Datagrid的增删改查的使用学习记录后一直想整理下基于Extjs4.2的Grid学习使用记录。苦于抽不出时间,一直拖到现在。不得不说,Extjs确实很强大,新版的Neptune风格也很入我眼,但毕竟没怎么用过,第一次用,也不敢上来就搞什么自定义组件,也就纯粹的model+store+panel声明式创建表格了。
抛开分页,抛开排序,今天只简单讲一下最近使用中总结出来的rest形式增删改查数据的方式。发现这种方式挺不错的,故而分享下。
代码Example如下:
定义Model
01.Ext.define('Person', {
02.extend:'Ext.data.Model',
03.fields: [{name:'id',
04.type:'int',
05.useNull:true
06.},'email','first','last'],
07.validations: [{ type:'length',
08.field:'email',
09.min: 1
10.}, {type:'length',
11.field:'first',
12.min: 1
13.}, {type:'length',
14.field:'last',
15.min: 1
16.}]
17.});
构造store、创建panel
001.var store = Ext.create('Ext.data.Store', {
002.autoLoad:true,
003.autoSync:true,
004.model:'Person',
005.proxy: {
006.type:'ajax',
007.api: {
008.read:'url/read',//查询
009.create:'url/create',//创建
010.update:'url/update',//更新
011.destroy:'url/destroy'//删除
012.},
013.reader: {
014.type:'json',
015.root:'data'
016.},
017.writer: {
018.type:'json'
019.}
020.},
021.listeners: {
022.write:function(store, operation){
023.var record = operation.getRecords()[0],
024.name = Ext.String.capitalize(operation.action),
025.verb;
026.
027.
028.if (name =='Destroy') {
029.record = operation.records[0];
030.verb ='Destroyed';
031.}else {
032.verb = name +'d';
033.}
034.Ext.example.msg(name, Ext.String.format("{0} user: {1}", verb, record.getId()));
035.
036.}
037.}
038.});
039.
040.var rowEditing = Ext.create('Ext.grid.plugin.RowEditing', {
041.listeners: {
042.cancelEdit:function(rowEditing, context) {
043.// Canceling editing of a locally added, unsaved record: remove it
044.if (context.record.phantom) {
045.store.remove(context.record);
046.}
047.}
048.}
049.});
050.
051.var grid = Ext.create('Ext.grid.Panel', {
052.renderTo: document.body,
053.plugins: [rowEditing],
054.width: 400,
055.height: 300,
056.frame:true,
057.title:'Users',
058.store: store,
059.iconCls:'icon-user',
060.columns: [{
061.text:'ID',
062.width: 40,
063.sortable:true,
064.dataIndex:'id'
065.}, {
066.text:'Email',
067.flex: 1,
068.sortable:true,
069.dataIndex:'email',
070.field: {
071.xtype:'textfield'
072.}
073.}, {
074.header:'First',
075.width: 80,
076.sortable:true,
077.dataIndex:'first',
078.field: {
079.xtype:'textfield'
080.}
081.}, {
082.text:'Last',
083.width: 80,
084.sortable:true,
085.dataIndex:'last',
086.field: {
087.xtype:'textfield'
088.}
089.}],
090.dockedItems: [{
091.xtype:'toolbar',
092.items: [{
093.text:'Add',
094.iconCls:'icon-add',
095.handler:function(){
096.// empty record
097.store.insert(0,new Person());
098.rowEditing.startEdit(0, 0);
099.}
100.},'-', {
101.itemId:'delete',
102.text:'Delete',
103.iconCls:'icon-delete',
104.disabled:true,
105.handler:function(){
106.var selection = grid.getView().getSelectionModel().getSelection()[0];
107.if (selection) {
108.store.remove(selection);
109.}
110.}
111.}]
112.}]
113.});
114.grid.getSelectionModel().on('selectionchange',function(selModel, selections){
115.grid.down('#delete').setDisabled(selections.length === 0);
很简单,使用api的方式,包括有增删查改,在前台的操作都会被extjs记录下来,再执行sync的时候就可以自动根据状态请求相应的url了。
下面是使用中遇到的一些小问题总结。
1、删除多行数据
例子里使用的是var selection = grid.getView().getSelectionModel().getSelection()[0];注意是加了个[0]的,所以要删除多行,直接取消这个[0],然后执行store即可,前提是你的表格没有限制只能选取一行,默认情况下,cellmodel的mode值为SINGLE,使用checkboxmodel就可以显示checkbox的同时实现多选了。
2、增删查改的同时进行传参
这个一开始同事懒得研究就直接在url里拼上去了,我觉得这样不妥,就查了下相关文章,最终得到两种实现方法
方法一:仅在查询时可用,设置store的autoload为false,手动载入store.load({//to do something});,这样使用查询是可以但是修改删除或者更新时就不好用了。于是有了方法二;
方法二:添加事件监听,在store里面设置linstener,监听beforeload时执行方法,设置Param,如:
1.listeners: {
2.beforeload:function(proxy, response, operation){
3.
4.}
5.}
3、后台动态构造表头不能设置renderer
由于业务特殊性,我们在后台构造json对象包装extjs grid所需的fields、columns,也正因此,不能在后台设置renderer等调用js函数的属性,我的解决方式是,后台添加固定标识,数据到前台后遍历添加所需renderer函数或者特殊编辑器等
后台交互
与后台的交互在一开始还是纠结了半天,没看清楚extjs的实现,原来使用这种方式的请求除了扩展参数以外,表格数据都是通过流交互的。这个在后台是不能直接使用request.getParamter(“xxx”);获取的,因为是使用流,所以需要通过get请求的流来读取数据,又因为是文本数据,所以直接request.getReader().readerLine();获取到的就是json格式的字符串了,接下来就需要自己根据需要进行转换了,个人还是使用json.simple,当然了,具体情况具体对待,如果你的数据有其他的比如文件上传之类的,就需要先获取inputstream再解析了。
就总结这么多了,有任何问题,欢迎留言交流