上次发了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再解析了。
就总结这么多了,有任何问题,欢迎留言交流