《易道客》源码剖析之三:两个公共页面(列表页和编辑页)

一、介绍

在系统中有两个公用的jsp页面,listCommon.jspaddCommon.jsp,分别是公共列表页和公共编辑页,这两个页面能够满足大多数开发的需要,也就是说,在开发中,不需要自己写jsp页面,只需要在action中作简单的配置,就可以满足大多数页面效果需求。之所能做到如此,是因此对于列表页和编辑页的元素,进行了高度的抽象,将会变化的元素提取成可配置项。如果实在有特殊效果,也可将jsp单独复制一份,简单改动实现。正是由于这两个页面的存在,对于提高开发效率有很大帮助。

 

二、效果展示

1、以下三个页面,均是由listCommon.jsp页面实现的。

 

 

 

2、以下三个页面,均是由addCommon.jsp页面实现的。

 

 

 

三、listCommon.jsp页面分析

1、如上图所示,之所以一个页面可以实现不同的效果,就是将不同的页面元素提取出来,做成可配置的。如列表页面中:标题,按钮、列表标题、列表数据、查询条件等元素。ListFere类就是存放这些配置元素的类,另外还有三类配合ListFere完成这样工作:Field(数据项,列表屏展示用),Button(按钮类,用于标识页面上部的一个按钮或左铡一个页签),QueryTj(查询条件项)。

 

2ListFere

 

public class ListFere
{
    private String title; //标题
    private Field[] fields;//数据项
    private List dataList;//数据
    private String clsName; //数据传递对象的类名,即dataList中存放对象的类型(通用list不需要,用在个人定制时产生id名称)
    private int firstFieldType = 1;//第一列类型:0 显示数据,1 单选按钮,2多选框
    private boolean havaSelectAll = false; //是否有全选按钮,针对多选框时的选择
    private boolean haveTop = true;//是否有顶部按钮
    private Button[] topButtons; //顶部显示按钮
    private boolean haveRight = false;//是否有右侧按钮
    private Button[] rightButtons;//右侧显示按钮
    private int rightSelectNo = 0;//右侧被选中的编号
    private boolean havaPage = true;//是否需要分页
    private boolean havaQuery = true;//是否有查询
    private QueryTj[] queryTj;//查询条件
    private String queryAction="list.action"; //查询请求的action
    private String jsName=""; //包含的js文件名称
    private QueryTj fastQueryTj=null; //快捷查询
    private String enterDoubleClickUrl="view.action";//回车或双击事件时,触发的Url

    /*
    * 在得到穿越和查询条件的隐藏控制显示字符串时,必须保留的值
    * 参见:src/com/abc/domain/common/util/show/ShowUtil.java
    */
    private String[] mastKeep; 

    /**
    * 根据值对象,得到显示的字符串,列表页面显示时调用 
    */
    public static String getShowValue(Object obj, Field f)
    {
        return ShowUtil.formatShowValue(obj,f.getShowType());
    }
    ......
}

 

 

3Field

 

public class Field
{
    private String title; //标题
    private String name;//字段名(属性名)
    private int width;//宽度
    
    /**
     * 具体使用地方:com.abc.domain.common.util.show.ShowUtil类的formatShowValue()方法
     * </br>当字段为date型时:默认只显日期 ,当为1时,显示日期时间。2:只显示时间。3:显示时分 4:显示日期+时分
     * </br>当字段为数值型时:默认原封输出,否则其值为保留的小数位数。
     * </br>当字段为boolean型时,如果为1,则输出“是、否”。
     * </br>当字段为字符串时,若为null,则输入空串,否则截取相应的长度,加上"..."
     */
    private int showType=-1;//显示类型
    private String align="center"; //数据显示的水平对齐方式
}

 

 

4Button

 

public class Button implements Comparable<Button>
{
    private int id;//编号,用来确认一组按钮时的先后顺序
    private String name; //名称
    private String link; //点击时的连接地址
    private String type; //用于权限控制
    private String imageUrl=null; //图片显示位置
    ......
}

 

 

5QueryTj

 

public class QueryTj
{
    private String title;//标题
    private String name;//名称
    /**
     * text:文本框
     * date:日期
     * time:时间
     * select:下拉框
     * organ:部门
     */
    private String type;//类型
    private int len;//长度
    private Map<String,String> data; //下拉框数据
    private String organData;//部门数据,格式:[编码,名称,父编码,级别],[编码,名称,父编码,级别]
    private int organLayer;//层次数
    private String fastClick=null;//快捷查询单击事件
    ......
}

 

 

6、联系人列表访问时action中的配置

 

@Action("list")
public String execute() throws Exception
{
		
    ListFere queryFere = new ListFere("联系人");

    //数据传递对象的类名,即dataList中存放对象的类型(通用list不需要,用在个人定制时产生id名称)
    queryFere.setClsName("LinkMan");
    
    //第一列类型:0 显示数据,1 单选按钮(默认),2多选框
    //queryFere.setFirstFieldType(1);
    
    //是否有分页,默认true
    //queryFere.setHavaPage(true);
	
    //在得到穿越和查询条件的隐藏控制显示字符串时,必须保留的值			
    //queryFere.setMastKeep(Constants.RELATION_+"Module_id");
    
    //包含js的名称,默认空值
    //queryFere.setJsName("/user/a.js");
    
    //设置显示字段
    queryFere.setFields(
        new Field("标 识", "id", 3), 
        new Field("联系人", "name", 10), 
        new Field("性别", "sex", 8), 
        new Field("职位", "post", 10), 
        new Field("手机", "phone", 12), 
        new Field("电话", "tel", 12),
        new Field("所属客户", "client.name", 21),
        new Field("主联系人", "mainLink", 8,1),
        new Field("是否归档", "lockit", 8,1),
        new Field("员工", "client.salesMan.trueName", 8)
        );
		
    //按钮设置
    //queryFere.setHaveTop(true);//是否有按钮,默认true
    //queryFere.setHavaSelectAll(false);//是否有多选框,针对复选框时,默认false
    
    Button[] buttonArr = new Button[]
    {		
        new Button(1, "全部联系人", "queryAll()","","/images/button/qblianxiren.gif"),
        new Button(1, "同单位人员", "aboutQuery()","","/images/button/sameroom.gif"),
        new Button(1, "设为主联系", "buttonClick('mainLinkman.action','all','update')","mainLinkman","/images/button/indexlianxiren.gif"),
        new Button(1, "查询", "locking()",""),
        new Button(1, "增加", "buttonClick('add.action','all','add')","add"),
        new Button(1, "修改", "buttonClick('update.action','all','update')","update"),
        new Button(1, "删除", "buttonClick('delete.action','all','delete')","delete"),
        new Button(1, "详述", "buttonClick('view.action','all','view')","")
    };

    //对按钮进行权限验证过滤
    queryFere.setTopButtons(ModuleFere.getCanShowButton(buttonArr, ModuleFactory_linkman.moduleId));   
    queryFere.setQueryAction("list.action");//查询请求的action,默认list.action
    Map<String, String> map_2=new LinkedHashMap<String, String>();
    map_2.put("", "...");
    map_2.put("true", "是");
    map_2.put("false", "否");
    queryFere.setQueryTj(
        new QueryTj("所属客户", "clientname", "text", 25),
        new QueryTj("员 工", "salesManName", "text", 25),
        new QueryTj("联系人", "name", "text", 25),
        new QueryTj("职 位", "post", "text", 25),
        new QueryTj("手 机", "phone", "text", 25),
        new QueryTj("电 话", "tel", "text", 25),
        new QueryTj("地 址", "homeAddress", "text", 50),
        new QueryTj("录入时间", "addTime", "date", 25)
    );
    //设置右侧按钮显示
    //queryFere.setHaveRight(false); //默认false
    //queryFere.setRightSelectNo(1); //默认选中项
    List<LinkMan> ls=linkmanService.query();
    List<LinkMan> linkManLs=new ArrayList<LinkMan>();
    for(int i=0;i<ls.size();i++){
        LinkMan bo=ls.get(i);
        Client client=bo.getClient();
        if(client!=null){
        	client.setName("<span style=\"color: #006699;cursor: pointer;\" onclick=\"window.open('"+ServletActionContext.getRequest().getContextPath()

+KhCons.viewPath+"?clientId="+client.getId()

+"','','height=600,width=1000,top=20,left=20,toolbar=no,menubar=no,scrollbars=yes,resizable=yes,location=no,titlebar=no,liaction=no, status=no,z-

look=yes,');\">"+client.getName()+"</span>");
        }
        bo.setClient(client);
        linkManLs.add(bo);
    }
    queryFere.setDataList(linkManLs);
    queryFere.setMastKeep(Constants.RELATION_+className+"_id");
    queryFere.setJsName("/jsp/kh/main/linkman/aboutQuery.js");
    fere=queryFere;
    return "commonList";
}

 

 

四、addCommon.jsp页面分析

公共编辑页面实现的原理和列表页相同,都是将可能变化的元素提出。辅助实现类有:AddFereFieldAddButton三个,具体代码不在粘贴,自己可到源程序中查看。使用方法可找到action中的相关方法查看。

在该页面中,对以下16种元素进行了包装:

1 文本项: txt

2 普通文本框 : text

3 整数: int

4 实数: double

5 日期: date

6 日期时间: dateTime

7 单选: radio

8 单选2radio2 //单选2 每个redio都增加检查语句,用在特殊场合,如:客户增加时,选不同的客户性质,执行js方法

9 复选框:checkbox

10 复选框(用表格展示,用于大数据量)checkbox_tab

11 下拉框: select

12 二级连动: select2

13 文本区域:textarea

14 密码框:password

15客户:client

16输出通行标题:title

 

五、其他

   这两个页面中,还加入了对权限控制、分页、记忆跳转的等功能的支持代码,有特殊需要新建页面时,最好将两个页面复制一份,然后更改。可能有诸多细节没有介绍到,想深入了解的可在源码中研究一下。

 

 

返回《易道客》主页

 

 

猜你喜欢

转载自rsy.iteye.com/blog/1754589