说在前面的话:
实例讲解:
实现从一张公告表读取公告信息并以列表展示的功能。本文中的源代码可通过这个链接下载。
开发环境:
Dev Tool: Eclipse 3.3
Web Server: Tomcat 5.5.23
Framework: Spring 2.0.6 + Hibernate 3.3.0 + Struts 1.2.8 + ecside_2.0_RC1
Database: Oracle 9i
实现步骤:
0) 准备工作
使用ecside工具,你需要准备的有:
1、ecside.jar
2、 ecside.tld标签
3、ecside.js
4、ecside.css
5、ecside使用table图片
注:以上内容均可在圈子中下载到。
1)配置ecside
需要在web.xml中配置ecside的过滤器,用于文件导出和语言编码,忘记配置的话,会出现“正在提交”的问题。
<!--
ecside export filter
-->
<
filter
>
<
filter-name
>
ecsideExport
</
filter-name
>
<
filter-class
>
org.ecside.filter.ECSideFilter
</
filter-class
>
<
init-param
>
<
param-name
>
useEasyDataAccess
</
param-name
>
<
param-value
>
true
</
param-value
>
</
init-param
>
<
init-param
>
<
param-name
>
useEncoding
</
param-name
>
<
param-value
>
true
</
param-value
>
</
init-param
>
<
init-param
>
<
param-name
>
encoding
</
param-name
>
<
param-value
>
UTF-8
</
param-value
>
</
init-param
>
</
filter
>
<
filter-mapping
>
<
filter-name
>
ecsideExport
</
filter-name
>
<
url-pattern
>
/*
</
url-pattern
>
</
filter-mapping
>
还需配置一下tld,
<
taglib
>
<
taglib-uri
>
/WEB-INF/ecside.tld
</
taglib-uri
>
<
taglib-location
>
/WEB-INF/taglib/ecside.tld
</
taglib-location
>
</
taglib
>
另外,还可以初始化ecside.properties文件,写这个文件的目的是:把公共的内容集中在一个文件中,方便使用。一旦我们使用ecside 组件,哪个这些配置信息就可以直接引用。形式可以如下:
########### table ###############
table.method=post
table.width=95%
table.pageSizeList=10,20,50,100,1000,2000,all
table.rowsDisplayed=10
table.sortable=true
########### column ###############
column.format.date=yyyy/MM/dd
column.format.number=0.##
column.format.currency=###,###,###
2) 在Struts Action中使用ecside
首先来简单介绍一下RSF(列表、排序、过滤)操作方式:
ecside支持两种RSF方式: 基于java collection层 和 基于数据库层,下面分别介绍:
基于java collection层
这是ec的默认实现方式, 最简单易用.你要做的就是将整个列表所要展现的全部数据放入collection 内,并交给EC来处理.其中RSF操作,全部由EC在内存中完成,由于你已经将全部数据放入了collection中,所以排序 过滤都是基于全部数据的.你要在DAO中做的就是一个 查询操作,SQL语句中不需要加入 关于排序 分页 过滤的代码.
这种方式的优点非常明显:实现简单.缺点同样明显,而且在很大程度上是致命的: 数据量大的时候速度慢,而且很可能OutOfMemory.
基于数据库层
在这种方式下,EC的角色发生了一点点变化。此时,EC负责把 collection 里的内容展现出来, 同时会向你提供RSF相关的参数。而这些参数需要你自己手动取得 并传入到DAO中(当然EC提供了很多方便的方法来帮助你取得这些参数),具体功能的实现需要你自己在DAO中组织相应的SQL语句。
这种方式的优缺点正好和方式一相反。
我这里采用第二种基于数据库层的分页方式实现列表,这时在JSP中使用ecside时,要将<ec:table>中的几个重要属性设定为limit。如: <ec:table filterRowsCallback="process/limit" sortRowsCallback="process/limit" retrieveRowsCallback="process/limit" ...> 这里filterRowsCallback表示过滤的Callback方式,sortRowsCallback表示排序的Callback方式,retrieveRowsCallback表示分页的Callback方式,这三个属性都需要设定为limit。(不熟悉的读者可以查询原版EC中的相关说明,不在这里详述。)
Struts Action的代码为:
/**/
/*
* 用ECSide構建列表
*
*/
public
ActionForward list(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
{
String v_type
=
request.getParameter(
"
type
"
);
//
0) 設定過濾條件
Map
<
String, Object
>
filterMap
=
new
HashMap
<
String, Object
>
();
//
filterMap.put("content", "test");
Map
<
String, Object
>
sortMap
=
new
HashMap
<
String, Object
>
();
sortMap.put(
"
createTime
"
,
"
desc
"
);
//
按照創建時間倒序排列
//
1) 設定ECSide分頁對象
Limit limit
=
RequestUtils.getLimit(request);
//
取总记录数
int
pageNo
=
RequestUtils.getPageNo(request);
int
pagesize
=
RequestUtils.getCurrentRowsDisplayed(request);
if
(pagesize
==
0
)
pagesize
=
PAGESIZE;
//
设置总记录数及每页记录数
int
totalRows
=
RequestUtils.getTotalRowsFromRequest(request);
if
(totalRows
<=
0
)
{
totalRows
=
getEntityManager()
.getCount(getEntityClass(), filterMap);
}
limit.setRowAttributes(totalRows, pagesize);
//
根據參數得到結果
List
<
Bulletin
>
result
=
getEntityManager().queryForListByCriter(
getEntityClass(), filterMap, sortMap,
((pageNo
-
1
)
*
pagesize), pagesize);
request.setAttribute(getEntityListName(), result);
request.setAttribute(
"
myPageSize
"
, getPageSize(request));
request.setAttribute(
"
type
"
, v_type);
return
mapping.findForward(LIST);
}
这里我构建了过滤条件及排序条件查询数据,通过queryForListByCriter方法,输入当前起始页及每页的显示条数在数据层得到所需数据。详见代码中的注释。另附数据处理层两个方法的代码:
/**//*分页查询数据*/
public List queryForListByCriter(Class entityClass, Map filter,
Map sortMap, int start, int everypage) {
Criteria criteria = getCriteria(entityClass);
setFilter(criteria, filter);
setSort(criteria, sortMap);
criteria.setFirstResult(start);
criteria.setMaxResults(everypage);
return criteria.list();
}
/**//*计算数据条数*/
public int getCount(Class entityClass, Map filter) {
Criteria criteria = getCriteria(entityClass);
setFilter(criteria, filter);
criteria.setProjection(Projections.rowCount());
return ((Integer) criteria.uniqueResult()).intValue();
}
注:ecside与ORM工具无关,不管你使用什么方法只要能获得一个集合就好,这里我用的是Hibernate获得的集合。
3)在JSP中使用ecside
需要注意的是:
1. items的值一定要和request.setAttribute(getEntityListName(), result); 属性一致
2. 可以引用属性名做为值显示,如:${bulletin.id}
3. <ec:column property="name" title="公告名称">property属性值一定是映射文件中的某个属性
<%
@ page contentType
=
"
text/html; charset=UTF-8
"
%>
<%
@ taglib uri
=
"
/WEB-INF/ecside.tld
"
prefix
=
"
ec
"
%>
<%
@ taglib uri
=
"
http://java.sun.com/jsp/jstl/core
"
prefix
=
"
c
"
%>
<%
@ taglib uri
=
"
http://java.sun.com/jsp/jstl/fmt
"
prefix
=
"
fmt
"
%>
<%
@ taglib uri
=
"
http://java.sun.com/jsp/jstl/functions
"
prefix
=
"
fn
"
%>
<
c:set
var
="ctx"
value
="${pageContext.request.contextPath}"
/>
<
html
>
<
head
>
<
meta
http-equiv
="Content-Type"
content
="text/html; charset=UTF-8"
/>
<
META
HTTP-EQUIV
="pragma"
CONTENT
="no-cache"
>
<
META
HTTP-EQUIV
="Cache-Control"
CONTENT
="no-cache, must-revalidate"
>
<
META
HTTP-EQUIV
="expires"
CONTENT
="0"
>
<
title
>
公告列表
</
title
>
<
link
rel
="stylesheet"
type
="text/css"
href
="${ctx}/module/bizAcceptance/resources/ecside/css/ecside_style.css"
/>
<
script
type
="text/javascript"
src
="${ctx}/module/bizAcceptance/resources/ecside/js/prototype_mini.js"
></
script
>
<
script
type
="text/javascript"
src
="${ctx}/module/bizAcceptance/resources/ecside/js/ecside.js"
></
script
>
<
script
type
="text/javascript"
src
="${ctx}/module/bizAcceptance/resources/ecside/js/ecside_msg_utf8_cn.js"
></
script
>
</
head
>
<
body
>
<
table
width
="100%"
border
="0"
cellspacing
="0"
cellpadding
="0"
>
<!--
校验信息
-->
<
tr
>
<
td
class
="left"
>
<%
@ include file
=
"
/module/commons/htmlmessages.jsp
"
%>
</
td
>
</
tr
>
<
tr
>
<
td
height
="30"
>
<
span
style
="align:left;font-size:9pt;"
>
請選擇公告
<
input
type
="button"
name
="Submit3"
value
='進
入' onclick
="doView()"
>
</
span
><
br
>
</
td
>
</
tr
>
<
tr
>
<
td
>
<
ec:table
items
="bulletins"
var
="bulletin"
retrieveRowsCallback
="limit"
filterRowsCallback
="limit"
action
="${ctx}/module/bulletin.do?method=list&type=${type}"
title
="我的公告列表"
useAjax
="false"
showPrint
="false"
width
="100%"
resizeColWidth
="true"
filterable
="false"
listWidth
="100%"
rowsDisplayed
="${myPageSize}"
pageSizeList
="${myPageSize},10,15,20,all"
xlsFileName
="公告列表.xls"
styleClass
="tableRegion"
style
="border:2px;table-layout:fixed;"
classic
="true"
>
<
ec:row
>
<
ec:column
property
="_0"
title
="選擇"
width
="6%"
>
<
input
type
="radio"
id
="radio_${GLOBALROWCOUNT}"
name
="checkedRadio"
value
="${bulletin.id}"
>
</
ec:column
>
<
ec:column
property
="_1"
title
="序號"
width
="6%"
>
${GLOBALROWCOUNT}
</
ec:column
>
<
ec:column
property
="name"
title
="公告名稱"
>
<
a
href
="JavaScript:doStarting('${affair.id}')"
title
="點擊查看"
><
c:out
value
="${bulletin.name}"
/></
a
>
</
ec:column
>
<
ec:column
property
="desn"
title
="描述"
ellipsis
="true"
/>
<
ec:column
property
="createBy"
title
="創建人"
width
="10%"
/>
<
ec:column
property
="createTime"
title
="創建時間"
width
="20%"
>
<
fmt:formatDate
value
="${bulletin.createTime}"
pattern
="yyyy-MM-dd HH:mm:ss"
/>
</
ec:column
>
<
ec:column
property
="_2"
title
="可執行操作"
>
<
a
href
="${ctx}/module/bulletin.do?method=edit&ID=${bulletin.id}"
><
img
src
="${ctx}/images/affairmgt/update.gif"
border
="0"
title
="編輯"
>
編輯
</
a
>
<
a
href
="${ctx}/module/bulletin.do?method=delete&ID=${bulletin.id}"
><
img
src
="${ctx}/images/affairmgt/delete.gif"
border
="0"
title
="移除"
>
移除
</
a
>
</
ec:column
>
</
ec:row
>
</
ec:table
>
</
td
>
</
tr
>
</
table
>
<
script
language
="javascript"
>
var
_confirm
=
"
false
"
;
var
confirmMsg
=
"
查看此公告?
"
;
var
urlPrefix
=
"
${ctx}/module/bulletin.do?method=view&ID=
"
;
function
doView(itemId)
{
if
(itemId
!=
null
)
{
if
(_confirm
==
'
false
'
||
confirm(confirmMsg))
{
ShowWaiting('正在加载数据,请稍候');
window.location
=
urlPrefix
+
itemId;
}
}
else
{
var
radio
=
document.getElementsByName('checkedRadio');
for
(i
=
0
; i
<
radio.length; i
++
)
{
if
(radio[i].checked)
{
if
(_confirm
==
'
false
'
||
confirm(confirmMsg))
{
itemId
=
radio[i].value;
ShowWaiting('正在加载数据,请稍候');
window.location
=
urlPrefix
+
itemId;
}
return
;
}
}
alert('請選擇一個公告!');
}
}
</
script
>
</
body
>
</
html
>
其中,<ec:column property="desn" title="描述" ellipsis="true" />,ellipsis属性实现单元格内数据过长的时候,自动截短并加"..."的功能,但是ie only!因为ff不支持 text-overflow: ellipsis; 使用ellipsis="true"的同时,还要为ec:table加上 style="table-layout:fixed;" (如果您已经使用了调整列宽功能 则不用添加)。
4) 启动服务,大功告成。
需要提醒一下,这里采用的是ECSide的默认样式,可根据您具体的需求改变样式文件。
THE END
posted on 2008-12-15 10:47
小立飞刀 阅读(9158)
评论(10) 编辑 收藏 所属分类:
User Interface