对于一些信息的展示,光用列表展示出来利用层级查询并不能给用户特别直观的感受,这时候我们利用tree型结构达到对用户体验效果的提升。(该文着重分析
easyuitree的展示)。
首先,我们设计一个节点类,将其属性进行封装整理。大概属性如下:
package com.szmz.csmp.vo;
import java.io.Serializable;
import java.util.List;
public class EasyUiTreeVO implements Serializable {
/**
*
*/
private static final long serialVersionUID = 2522698711285809086L;
private Integer id; //菜单ID
private String text; //菜单显示名称
private Boolean checked = false; //是否选中
private List<EasyUiTreeVO> children; //子节点
private Integer rank;//层级
private Integer parentId;//父类节点id
private String state;//节点状态
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Boolean getChecked() {
return checked;
}
public void setChecked(Boolean checked) {
this.checked = checked;
}
public List<EasyUiTreeVO> getChildren() {
return children;
}
public void setChildren(List<EasyUiTreeVO> children) {
this.children = children;
}
public Integer getRank() {
return rank;
}
public void setRank(Integer rank) {
this.rank = rank;
}
public Integer getParentId() {
return parentId;
}
public void setParentId(Integer parentId) {
this.parentId = parentId;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
前台代码很简单,通过接收后台传来的jsonArray直接刷出来即可。
<script>
$('#tt').tree({
url: 'evaluatManageAction.do?method=loadEvaluat&year='+year,
onClick:function(node){
var url="evaluatManageAction.do?method=toDetail&id="+node.id+"&rank="+node.rank;
$('#sysframe').attr('src',url);
}
});
</script>
<ul id="tt" class="easyui-tree" data-options="state:'closed'">
</ul>
接着就是在后台把这个树架起来通过jsonArray格式传过来了。
Action中代码如下:
/**
* 加载树
* @return
* @throws Exception
*/
public void loadEvaluat(ActionForm form, HttpServletRequest request,
HttpServletResponse response) throws Exception {
DataRecord dataRecord =getDataRecord(request);
dataRecord.setString("status", "5");//加载的树 必须状态为 已备案的,删除的 不显示
List<EasyUiTreeVO> list = evaluatManageService.loadEvaluat(dataRecord);
if(null!=list &&list.size()>0){ //判断是否为空,若为空则创建一个根节点传出
JSONArray jsonArray =JSONArray.fromObject(list);
response.setCharacterEncoding("utf-8");
response.setContentType("application/json");
System.out.println(jsonArray.toString());
String data = jsonArray.toString();
System.out.println(data);
response.getWriter().write(data);
response.getWriter().flush();
response.getWriter().close();
}else{ //这块就不做过多解释了
List<EasyUiTreeVO> volist = new ArrayList<EasyUiTreeVO>();
JSONObject jsonObj = new JSONObject();
JSONArray jsonArray =JSONArray.fromObject(volist);
response.setCharacterEncoding("utf-8");
response.setContentType("application/json");
System.out.println(jsonArray.toString());
String data = jsonArray.toString();
System.out.println(data);
response.getWriter().write(data);
response.getWriter().flush();
response.getWriter().close();
}
}
service方法如下:
/**
* 获取组装好的树
*/
public List<EasyUiTreeVO> loadEvaluat(DataRecord dataRecord){
List<CsmpPeIndex> list = evaluatManageDao.getCsmpPeIndexTree(dataRecord);
List<EasyUiTreeVO> tree1 = groupList(list,3);
List<EasyUiTreeVO> tree2 = groupList(list,2);
List<EasyUiTreeVO> tree3 = groupList(list,1);
List<EasyUiTreeVO> tree4 = groupList(list,0);
List<EasyUiTreeVO> test1 =createMenuTree(tree2,tree1);
List<EasyUiTreeVO> rootTree =createMenuTree(tree3,tree2);
if(null!=tree4 &&tree4.size()>0){
if(null!=rootTree&&rootTree.size()>0){
rootTree.get(0).setText(tree4.get(0).getText());
}else{
rootTree = new ArrayList<EasyUiTreeVO>();
EasyUiTreeVO vo = new EasyUiTreeVO();
if(null!=tree4.get(0)&&null!=tree4.get(0).getChildren()&&tree4.get(0).getChildren().size()>0){
vo.setId(tree4.get(0).getChildren().get(0).getId());
}
vo.setText(tree4.get(0).getText());
vo.setRank(0);
rootTree.add(vo);
}
}else{
if(null!=rootTree &&rootTree.size()>0){
List<CsmpPeIndex> rootList = evaluatManageDao.getCsmpPeIndexByYear(rootTree.get(0).getId().toString(), dataRecord.getString("year"));
rootTree.get(0).setText(rootList.get(0).getIndexName());
}
}
return rootTree;
}
其中调用到两个方法groupList和createMenuTree。
groupList作用是对同一层级的节点的基本信息与上级节点关联组装
createMenuTree是将groupList整理后的一个节点集合及上级节点集合进行关联组装
所以这两个方法都是从下级到上级加载的,如果改变顺序可能会出现组装混乱。
先是groupList方法:
/**
* @param list 节点的基本信息
* @param rank 层级(实体中取得)
* @return
*/
public List<EasyUiTreeVO> groupList(List<CsmpPeIndex> list,int rank){
if(null==list||list.size()==0){
return null;
}
Map<String,List> map = new HashMap<String,List>();
List<EasyUiTreeVO> headList = new ArrayList<EasyUiTreeVO>();
for(int i=0;i<list.size();i++){
CsmpPeIndex csmpPeIndex = (CsmpPeIndex)list.get(i);
if(new Integer(csmpPeIndex.getIndexType()).intValue()==rank){
String name = csmpPeIndex.getParentIndex(); //上级节点id
/***层级为root节点时特殊处理***/
if(0==rank){
name=csmpPeIndex.getParentIndex()+"-"+csmpPeIndex.getIndexName();
}
if(map.containsKey(name)){ //在map中搜寻是否已经创建节点集合,如果有,在该集合中添加该类的节点
EasyUiTreeVO treeVO = new EasyUiTreeVO();
treeVO.setId(new Integer(csmpPeIndex.getIndexId()));
if(StringUtils.hasText(csmpPeIndex.getIndexScore()) && rank > 2){
treeVO.setText(csmpPeIndex.getIndexName()+"("+csmpPeIndex.getIndexScore()+")");
}else{
treeVO.setText(csmpPeIndex.getIndexName());
}
treeVO.setRank(new Integer(csmpPeIndex.getIndexType()));
treeVO.setParentId(new Integer(csmpPeIndex.getParentIndex()));
map.get(name).add(treeVO);
}else{
List<EasyUiTreeVO> uiList = new ArrayList(); //建立一个集合,把兄弟元素归类,先存一个。
EasyUiTreeVO data = new EasyUiTreeVO();
data.setId(new Integer(csmpPeIndex.getIndexId()));
if(StringUtils.hasText(csmpPeIndex.getIndexScore()) && rank > 2){
data.setText(csmpPeIndex.getIndexName()+"("+csmpPeIndex.getIndexScore()+")");
}else{
data.setText(csmpPeIndex.getIndexName());
}
data.setRank(new Integer(csmpPeIndex.getIndexType()));
uiList.add(data);
map.put(name,uiList);
}
}
}
for (String key : map.keySet()) {
EasyUiTreeVO headVO = new EasyUiTreeVO();
/***层级为root节点时特殊处理***/
if(key.indexOf("-")>0){
String[] values= key.split("-");
headVO.setId(new Integer(values[0]));
headVO.setText(values[1]);
}else{
headVO.setId(new Integer(key));
}
/******/
// headVO.setId(new Integer(key));
headVO.setChildren(map.get(key));
headList.add(headVO);
}
return headList;
}
再是
createMenuTree方法:
/**
* 将两个层级的节点拼装
* @param list
* @param list2
* @return
*/
public List<EasyUiTreeVO> createMenuTree(List<EasyUiTreeVO> list, List<EasyUiTreeVO> list2) {
if (null == list || list.size() == 0 || null == list2
|| list2.size() == 0) {
return null;
}
for (EasyUiTreeVO uitree : list) {
if (null != uitree.getChildren() && uitree.getChildren().size() > 0) {
List<EasyUiTreeVO> listRemove = new ArrayList<EasyUiTreeVO>(){};
for (EasyUiTreeVO uiTreeVO : uitree.getChildren()) {
int score = 0;
for (EasyUiTreeVO tree : list2) {
if (uiTreeVO.getId().equals(tree.getId())) {
uiTreeVO.setChildren(tree.getChildren());
for (EasyUiTreeVO voTreeScore : tree.getChildren()) {
if (StringUtils.hasText(voTreeScore
.getParentCode())) {
if (voTreeScore.getParentCode()
.indexOf("-") == -1) {
score = score
+ Integer.parseInt(voTreeScore
.getParentCode());
}
}
}
uiTreeVO.setText(uiTreeVO.getText() + "(" + score
+ ")");
uiTreeVO.setParentCode(String.valueOf(score));
}
}
if(score == 0){//如果没有子项就remove掉
listRemove.add(uiTreeVO);
}
}
//开始remove
if(null!=listRemove && listRemove.size() > 0){
for (EasyUiTreeVO removeVO : listRemove) {
uitree.getChildren().remove(removeVO);
}
}
}
}
return list;
}
效果如下:
这是本人接触的第一个树形结构展示的案例,若有不足或改进之处还望各位大神指点。
本文介绍展现方式适用于数据量小的情况,若数据量过大页面加载时间过长,给用户体验效果并不理想。下一篇介绍如何解决这一问题