最近在组队在写老师布置的电子商城项目。在我写到商品录入时,需要调出数据库中商品分类(级联),查了资料,有些说直接把所有分类从数据库中取出,然后用javascript实现级联,但是这种方法的缺点是数据冗余度高,于是看到有人推荐用ajax实现。看了几段别人的代码就开始自己着手写了,首先需要下载一个jar包(ajax4jsf),因为在jsf代码中需要用到ajax的话,必须使用这个jar包。接着在jsp页面的头部写上<%@ taglib prefix="a4j" uri="https://ajax4jsf.dev.java.net/ajax"%>。然后就是写一些组件来显示商品的种类,,manageBean中根据所选种类获得下一级的所属种类,关键代码贴出来看下。
jsp文件:
<!--第一级分类-->
<h:selectOneMenu id="cd1" value="#{inputNewGoodsBean.c1Name }" valueChangeListener="#{inputNewGoodsBean.c1IDChange }" immediate="true">
<f:selectItems value="#{inputNewGoodsBean.c1Catagories }"/>
<a4j:support event="onchange" reRender="cd2,cd3" immediate="true"/><!--这边就是用到了ajax的东西了,cd3是第三级分类的selectOneMenu的id-->
</h:selectOneMenu>
<!--第二级分类-->
<h:selectOneMenu id="cd2" value="#{inputNewGoodsBean.c2Name }" valueChangeListener="#{inputNewGoodsBean.c2IDChange }" immediate="true">
<f:selectItems value="#{inputNewGoodsBean.c2Catagories }"/>
<a4j:support event="onchange" reRender="cd3" immediate="true"/>
</h:selectOneMenu>
以上的immediate="true"是必不可少的。
还有第三级分类就不写了,原理是一样的。接下来看下inputNewGoodsBean的关键东西。
private List<SelectItem> c1Catagories;//从数据库中获得的第一级分类就存储在这个变量中;
private List<SelectItem> c2Catagories;//第二级分类存储在这里
//初始化,获得第一级的所有分类:主要是那个initCatagory1方法;
public InputNewGoodsBean(){
c1Catagories = new ArrayList<SelectItem>();
c2Catagories = new ArrayList<SelectItem>();
initCatagory1();
}
private void initCatagory1(){
GoodsManager gm = this.getGoodsManager();//这个GoodsManager是接口,getGoodsManager方法里面的是jndi查找
c1Catagories = gm.getCatagory1();//getCatagory1里面的方法是从数据中获得第一级的所有分类
}
接下来要写如何根据选中的第一级分类来显示该分类下的第二级分类,这时就是那句a4j:support event="onchange" reRender="..."....起作用的时候了
获得选中的第一类的信息,然后根据这个信息在数据库中找到该分类下的第二类的所有分类。这个主要是看数据表设计了。
public void c1IDChange(ValueChangeEvent event){
c2Catagories.clear();
String c1IDString = (String) event.getNewValue();
int c1ID = Integer.parseInt(c1IDString);//感觉有点多此一举
System.out.println(c1ID);
try{
GoodsManager gm = this.getGoodsManager();
System.out.println("catagories clear...");
c2Catagories = gm.getCatagory2(c1ID);
}catch(Exception e){
e.printStackTrace();
}
}