上次发了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: true06. }, '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再解析了。
就总结这么多了,有任何问题,欢迎留言交流
浙公网安备 33010602011771号