2007-09-11
dwr作为数据源的extjs grid crud解决方案
这里是前人的伟大成果。用了以后不太爽,主要问题在ListRangeReader,既然已经要求服务端按照自己的要求组装数据了,为什么还要在客户端做这许多数据解析重组的工作?于是自己做了一个略显干净的实现。
extjs grid所要求的datastore实际上是这样格式的对象:
其中的records的每一项为Ext.data.Record类型,这个类型担负着与grid交互的责任,但是其数据部分是简单的:
我们先在服务器端按照以上格式把数据组装好。首先是Record
之后是datastore
如果没有特殊要求,使用缺省实现就行了
定义一个dwr service模板
这里顺便给出一个具体service实现的例子供参考
以上是服务端要做的事情。
客户端实现DWRReader(DWRProxy不变)替代ListRangeReader。
这样dataStore的初始化就很简单了
最后给几条友情提示:
1. 增删改的操作与grid没有多大关系,可以参考原文自行实现。需要提醒的是,原文中的代码有比较严重的bug,会导致每次添加和修改操作都新建一个对话框实例
2. 以上的java代码使用了SpringSide和apache commons BeanUtils的部分功能,请自行集成,这些对本方案不是必需的,重要的是领会精神
3. 请为你的model声明Converter,另外,dwr的EnumConverter有bug,需要类似于StringConverter在ConvertOutboundData中做encoding
4. 由于dwr的bug,使用本方案有时会出现Warning multiple matching methods. Using first match.的警告,不影响系统运行
5. 总体来说,dwr的使用能够让extjs的代码干净一些,extjs+dwr+spring是我推荐的组合,前提是你有时间和精力去玩儿javascript的诡异语法
6. javaeye的html编辑器会吞掉java代码中的范型,另外草稿第二次保存会丢失我的数据。
extjs grid所要求的datastore实际上是这样格式的对象:
js 代码
- {
- success: true or false,
- records: 当前页中的数据项,
- totalRecords:所有数据总数
- }
其中的records的每一项为Ext.data.Record类型,这个类型担负着与grid交互的责任,但是其数据部分是简单的:
js 代码
- {
- id: 数据对象的id;
- data: 真实的数据对象;
- }
我们先在服务器端按照以上格式把数据组装好。首先是Record
| @DataTransferObject public class ExtRecord long id; T data; public ExtRecord(long id, T obj) { this.id = id; this.data = obj; } public long getId() { return id; } public void setId(long id) { this.id = id; } public T getData() { return data; } public void setData(T data) { this.data = data; } } |
| @DataTransferObject public interface ExtDataStore @RemoteProperty public boolean isSuccess(); @RemoteProperty public List @RemoteProperty public int getTotalRecords(); } |
如果没有特殊要求,使用缺省实现就行了
| public class DefaultExtDataStore boolean success; List int totalRecords; public boolean isSuccess() { return success; } public void setSuccess(boolean success) { this.success = success; } public List return records; } public void setRecords(List this.records = records; } public int getTotalRecords() { return totalRecords; } public void setTotalRecords(int totalRecords) { this.totalRecords = totalRecords; } } |
定义一个dwr service模板
| public abstract class ExtDWRService<T, M extends HibernateEntityDao<T>> { M manager; protected void setManager(M manager) { this.manager = manager; } protected ExtDataStore<T> list(int start, int limit, String sort) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { DefaultExtDataStore<T> result = new DefaultExtDataStore<T>(); result.setSuccess(true); List<T> all = manager.getAll(); result.setTotalRecords(all.size()); List<ExtRecord<T>> records = new ArrayList<ExtRecord<T>>(); for(T item : all.subList(start, Math.min(start+limit, all.size()))){ records.add(new ExtRecord<T>( Long.valueOf(BeanUtils.getProperty(item, "id")), item)); } result.setRecords(records); return result; } protected void update(long id, T newValues) throws IllegalAccessException, InvocationTargetException { T oldValues = manager.get(id); BeanUtils.setProperty(newValues, "id", id); org.springside.core.utils.BeanUtils.copyProperties(oldValues, newValues); manager.save(oldValues); } protected T load(long id){ return manager.get(id); } protected void add(T newValues) throws IllegalAccessException, InvocationTargetException, InstantiationException { T newObj = (T) newValues.getClass().newInstance(); org.springside.core.utils.BeanUtils.copyProperties(newObj, newValues); manager.save(newObj); } protected void del(long[] ids){ for(long id: ids){ manager.removeById(id); } } } |
这里顺便给出一个具体service实现的例子供参考
| public class AdvPositionService extends ExtDWRService<AdvPosition, AdvPositionManager> { public void setAdvPositionManager(AdvPositionManager advPositionManager) { this.setManager(advPositionManager); } @RemoteMethod public ExtDataStore<AdvPosition> list(int start, int limit, String sort) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { return super.list(start, limit, sort); } @RemoteMethod public void add(AdvPosition newValues) throws IllegalAccessException, InvocationTargetException, InstantiationException { super.add(newValues); } @RemoteMethod public void update(long id, AdvPosition newValues) throws IllegalAccessException, InvocationTargetException { super.update(id, newValues); } @RemoteMethod public void del(long[] ids) { super.del(ids); } @RemoteMethod public AdvPosition load(long id) { return super.load(id); } } |
以上是服务端要做的事情。
客户端实现DWRReader(DWRProxy不变)替代ListRangeReader。
js 代码
- Ext.data.DWRReader = function() {
- Ext.data.DWRReader.superclass.constructor.call(this, null, []);
- }
- Ext.extend(Ext.data.DWRReader, Ext.data.DataReader, {
- read: function(response) {
- var recordType = this.recordType;
- var records = [];
- for (var i = 0; i < response.records.length; i++) {
- var record = response.records[i]
- records[records.length] = new recordType(record.data, record.id);
- }
- response.records = records;
- return response;
- }
- })
js 代码
- function init_dataStore() {
- dataStore = new Ext.data.Store({
- proxy: new Ext.data.DWRProxy(AdvPositionService.list, true),
- reader: new Ext.data.DWRReader()
- });
- }
- init_dataStore()
- dataStore.load({params:{start:0, limit:myPageSize}});
最后给几条友情提示:
1. 增删改的操作与grid没有多大关系,可以参考原文自行实现。需要提醒的是,原文中的代码有比较严重的bug,会导致每次添加和修改操作都新建一个对话框实例
2. 以上的java代码使用了SpringSide和apache commons BeanUtils的部分功能,请自行集成,这些对本方案不是必需的,重要的是领会精神
3. 请为你的model声明Converter,另外,dwr的EnumConverter有bug,需要类似于StringConverter在ConvertOutboundData中做encoding
4. 由于dwr的bug,使用本方案有时会出现Warning multiple matching methods. Using first match.的警告,不影响系统运行
5. 总体来说,dwr的使用能够让extjs的代码干净一些,extjs+dwr+spring是我推荐的组合,前提是你有时间和精力去玩儿javascript的诡异语法
6. javaeye的html编辑器会吞掉java代码中的范型,另外草稿第二次保存会丢失我的数据。
评论
返回的结构不够好吧?附带数据校验呢?例如说,在一个添加和列表同一个页面时,添加数据后同时刷新列表。那么有可能做数据校验时,将错误的信息返回,这时候需要显示错误信息。而不是列表数据。那么你的错误信息如何返回?
我觉得可以采用
String jsonDataString; //服务器端组织出的json数据
List errorMsg; //多行的错误信息,采用validator国际化效验返回,如果列表为空表示没错误。
来统一处理
然后将业务Bean用AOP方式加工处理
我觉得可以采用
String jsonDataString; //服务器端组织出的json数据
List errorMsg; //多行的错误信息,采用validator国际化效验返回,如果列表为空表示没错误。
来统一处理
然后将业务Bean用AOP方式加工处理
发表评论
最近加入圈子
最新评论
-
dwr作为数据源的extjs gr ...
:D :) :( 引用
-- by qqggcc -
Acegi中的FilterInvocati ...
能具体介绍一下用法么?该怎么配置?
-- by godson_2003 -
dwr作为数据源的extjs gr ...
这样在grid 点击列的排序问题怎么解决呢 ??
-- by sariy -
dwr作为数据源的extjs gr ...
不知道有没有关于tree的方案?
-- by kaki -
Acegi中的FilterInvocati ...
请问一下!我的requestMap为什么一直都是空值啊?
-- by hunter0116







评论排行榜