简介

Ajax有人形容为“新瓶里的老酒”,这一点也不为过,这里就不多介绍了。在这技术日新月异的世界里,真是不g不知道,一g吓一跳。给大家推荐一个实惠的:http://www.blogjava.net/eamoi

AjaxTags是一个开源的项目,目前进展你自己看吧:http://ajaxtags.sourceforge.net/,里面有源码、demo和doc。

 

背景

历史解决方法

1、  在父select元素的onChange事件中增加方法,调用action去填充子select元素。

2、  方法1 的改进,将两个或多个连动select元素放到一个iframe中。

3、  将父select元素和子select元素的内容,在页面初始化时装载到js的变量中,由父select元素的onChange事件直接调用js实现。

4、  方法3 的变形,将父select元素和子select元素的内容,写成独立的js。

历史方法缺点

方法

缺点

方法1

页面得全部刷新,须记住其他已填的内容

方法2

页面复杂,iframe得全部刷新

方法3

对于用户的每一次界面操作都得全部加载数据,资源浪费,代码繁多

方法4

数据库的字典表和js同步有很大问题,更新麻烦

我们的目的

1、  页面无需全部刷新;

2、  与字典表更新同步;

3、  减少网络传输资源损耗;

使用方法

准备工作

1、  http://ajaxtags.sourceforge.net/上下载AjaxTags的最新版本,有源码、demo和doc。

2、  按照demo所示,拷贝资源文件:css、js和lib,还要注意WEB-INF 目录下的ajaxtags.tld。

开始使用

1、  web.xml文件中加入

  <taglib>

     <taglib-uri>/WEB-INF/ajaxtags.tld</taglib-uri>

     <taglib-location>/WEB-INF/ajaxtags.tld</taglib-location>

  </taglib>

2、  如果你的连动会多处使用,就写成一个.inc文件,使用时就引进来:<%@ include file="/inc/fathertoson.inc"%>

<%@ page contentType="text/html;charset=GBK"%>

 

<!--ajax的标签库-->

<%@ taglib uri="/WEB-INF/ajaxtags.tld" prefix="ajax"%>

<!--ajax的css-->

<link href="css/ajaxtags.css" rel="stylesheet" type="text/css" />

<link href="css/displaytag.css" rel="stylesheet" type="text/css" />

<!--ajax的js-->

<script src="js/prototype-1.3.1.js"></script>

<script src="js/ajaxtags-1.1.5.js"></script>

 

<tr>

    <td>父select</td>

    <td>

        <!—struts的标签-->

        <html:select property="father" value="">

            <html:option value="">&nbsp;</html:option>

            <html:options collection="fatherCollection" property="id" labelProperty="name" />

        </html:select>

    </td>

   

    <td>子select</td>

    <td>

        <select name="son">

            <option selected>&nbsp;</option>

        </select>

    </td>

</tr>

 

<!--父子连动-->

<ajax:select

  baseUrl="fatherToSon.do"

  source="father"

  target="son"

  parameters="fathername={father}" /> 

 

解释一下:

baseUrl 调用action的url;

source 父select

target 子select

parameters="fathername={father}" fathername为action中获得父select值的参数

 

3、  Action的写法

public class FatherToSonAction extends BaseAjaxAction {

 

    public String getXmlContent(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {

        // 从界面获得父select的值,注意该处使用的是"fathername"而不是"father"

        String selectValue = request.getParameter("fathername");

       

        // 从数据库中得到子select的列表

        ArrayList list = (ArrayList) ...;

       

        // 子select的列表中的对象为子字典对象,具有"name", "id"属性

        return new AjaxXmlBuilder().addItems(list, "name", "id").toString();

    }

 

}

其中BaseAjaxAction和AjaxXmlBuilder可以参照ajax源码进行修改,修改后代码如下:

//================================ AjaxXmlBuilder======================

import java.lang.reflect.InvocationTargetException;

import java.util.ArrayList;

import java.util.Collection;

import java.util.Iterator;

import java.util.List;

 

import org.apache.commons.beanutils.BeanUtils;

import org.apache.commons.lang.builder.ToStringBuilder;

 

/**

 * Helper class to build valid XML typically returned in a response to the client.

 *

 * 生成xml类型文件的帮助类,我们可以将xml文件放到response中返回给客户端

 *

 * @author Darren Spurgeon

 * @version $Revision$ $Date$

 */

public class AjaxXmlBuilder {

 

    private String encoding = "UTF-8";

 

    private List items = new ArrayList();

 

    public String getEncoding() {

        return encoding;

    }

 

    public void setEncoding(String encoding) {

        this.encoding = encoding;

    }

 

    /**

     * Add item to XML.

     *

     * @param name

     *            The name of the item

     * @param value

     *            The value of the item

     * @return

     */

    public AjaxXmlBuilder addItem(String name, String value) {

        items.add(new Item(name, value, false));

        return this;

    }

 

    /**

     * Add item wrapped with inside a CDATA element.

     *

     * @param name

     *            The name of the item

     * @param value

     *            The value of the item

     * @return

     */

    public AjaxXmlBuilder addItemAsCData(String name, String value) {

        items.add(new Item(name, value, true));

        return this;

    }

 

    /**

     * Add items from a collection.

     *

     * @param collection

     * @param nameProperty

     * @param valueProperty

     * @return

     * @throws IllegalAccessException

     * @throws InvocationTargetException

     * @throws NoSuchMethodException

     */

    public AjaxXmlBuilder addItems(Collection collection, String nameProperty,

            String valueProperty) throws IllegalAccessException,

            InvocationTargetException, NoSuchMethodException {

        return addItems(collection, nameProperty, valueProperty, false);

    }

 

    /**

     * Add items from a collection.

     *

     * @param collection

     * @param nameProperty

     * @param valueProperty

     * @return

     * @throws IllegalAccessException

     * @throws InvocationTargetException

     * @throws NoSuchMethodException

     */

    public AjaxXmlBuilder addItems(Collection collection, String nameProperty,

            String valueProperty, boolean asCData)

            throws IllegalAccessException, InvocationTargetException,

            NoSuchMethodException {

        for (Iterator iter = collection.iterator(); iter.hasNext();) {

            Object element = (Object) iter.next();

            String name = BeanUtils.getProperty(element, nameProperty);

            String value = BeanUtils.getProperty(element, valueProperty);

            if (asCData) {

                items.add(new Item(name, value, false));

            } else {

                items.add(new Item(name, value, true));

 

            }

        }

        return this;

    }

 

    /**

     * Add items from a collection as CDATA element.

     *

     * @param collection

     * @param nameProperty

     * @param valueProperty

     * @return

     * @throws IllegalAccessException

     * @throws InvocationTargetException

     * @throws NoSuchMethodException

     */

    public AjaxXmlBuilder addItemsAsCData(Collection collection,

            String nameProperty, String valueProperty)

            throws IllegalAccessException, InvocationTargetException,

            NoSuchMethodException {

        return addItems(collection, nameProperty, valueProperty, true);

    }

 

    /**

     * @see java.lang.Object#toString()

     */

    public String toString() {

        StringBuffer xml = new StringBuffer().append("<?xml version=\"1.0\"");

        if (encoding != null) {

            xml.append(" encoding=\"");

            xml.append(encoding);

            xml.append("\"");

        }

        xml.append(" ?>");

 

        xml.append("<ajax-response>");

        xml.append("<response>");

        for (Iterator iter = items.iterator(); iter.hasNext();) {

            Item item = (Item) iter.next();

            xml.append("<item>");

            xml.append("<name>");

            if (item.isAsCData()) {

                xml.append("<![CDATA[");

            }

            xml.append(item.getName());

            if (item.isAsCData()) {

                xml.append("]]>");

            }

            xml.append("</name>");

            xml.append("<value>");

            if (item.isAsCData()) {

                xml.append("<![CDATA[");

            }

            xml.append(item.getValue());

            if (item.isAsCData()) {

                xml.append("]]>");

            }

            xml.append("</value>");

            xml.append("</item>");

        }

        xml.append("</response>");

        xml.append("</ajax-response>");

 

        return xml.toString();

 

    }

 

}

 

/**

 * A generic item class, basically representing a name-value pair.

 *

 * 一个通用的item类,代表了一个name-value对

 *

 * @author Darren Spurgoen

 * @version $Revision$ $Date$

 */

class Item {

 

    private String name;

 

    private String value;

 

    private boolean asData;

 

    /**

     * Constructor for Item.

     */

    public Item() {

        super();

    }

 

    /**

     * Constructor for Item.

     *

     * @param name

     * @param value

     */

    public Item(String name, String value, boolean asData) {

        super();

        this.name = name;

        this.value = value;

        this.asData = asData;

    }

 

    /**

     * @return Returns the name.

     */

    public String getName() {

        return this.name;

    }

 

    /**

     * @param name

     *            The name to set.

     */

    public void setName(String name) {

        this.name = name;

    }

 

    /**

     * @return Returns the value.

     */

    public String getValue() {

        return this.value;

    }

 

    /**

     * @param value

     *            The value to set.

     */

    public void setValue(String value) {

        this.value = value;

    }

 

    /**

     * @return Returns the asCData.

     */

    public boolean isAsCData() {

        return this.asData;

    }

 

    /**

     * @param asData

     *            The asData to set.

     */

    public void setAsData(boolean asData) {

        this.asData = asData;

    }

 

    /**

     * @see java.lang.Object#toString()

     */

    public String toString() {

        return new ToStringBuilder(this).append("name", name).append("value",

                value).append("asData", asData).toString();

    }

}

//========================== BaseAjaxAction==============================

 

import java.io.PrintWriter;

 

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import org.apache.struts.action.Action;

import org.apache.struts.action.ActionForm;

import org.apache.struts.action.ActionForward;

import org.apache.struts.action.ActionMapping;

 

/**

 * Ajax应用的祖先抽象类,将xml文件类型数据放到响应流中

 *

 * @author luzhilin

 *

 */

public abstract class BaseAjaxAction extends Action {

 

    /**

     * @see Action#execute(ActionMapping, ActionForm, HttpServletRequest,

     *      HttpServletResponse)

     */

    public final ActionForward execute(ActionMapping mapping, ActionForm form,

            HttpServletRequest request, HttpServletResponse response)

            throws Exception {

 

        String xml = null;

        try {

            xml = getXmlContent(mapping, form, request, response);

        } catch (Exception ex) {

            // Send back a 500 error code.

            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,

                    "Can not create response");

            return null;

        }

 

        // Set content to xml

        response.setContentType("text/xml; charset=UTF-8");

        response.setHeader("Cache-Control", "no-cache");

        PrintWriter pw = response.getWriter();

        pw.write(xml);

        pw.close();

 

        return null;

    }

 

    /**

     * Each child class should override this method to generate the specific XML

     * content necessary for each AJAX action.

     *

     * 每一个子类都必须重写此方法,用于生成特定的xml文件数据流

     *

     * @param mapping

     * @param form

     * @param request

     *            the {@javax.servlet.http.HttpServletRequest} object

     * @param response

     *            the {@javax.servlet.http.HttpServletResponse} object

     * @return a {@java.lang.String} representation of the XML response/content

     * @throws Exception

     */

    public abstract String getXmlContent(ActionMapping mapping,

            ActionForm form, HttpServletRequest request,

            HttpServletResponse response) throws Exception;

 

}

进一步思考的问题

1、   多层连动怎么实现;

2、  多组连动,我们的 action 怎么实现;

posted on 2006-03-08 21:12 野草 阅读(2607) 评论(7)  编辑  收藏 所属分类: ajax

评论:
# re: 在Struts中使用AjaxTags解决连动问题 2006-10-24 18:30 | cdy
为什么我按你说的做了一点反应都没有阿?
今天搞了一天,请指点一点,就是在选中一个select后第二个没有反应
我把我的代码发给你看一下  回复  更多评论
  
# re: 在Struts中使用AjaxTags解决连动问题 2006-10-24 18:31 | cdy
这个是页面代码

<%@ include file="taglibs.jsp"%>

<html>
<head>
<script type="text/javascript" src="<%=request.getContextPath()%>/js/prototype-1.4.0.js"></script>
<script type="text/javascript" src="js/scriptaculous.js"></script>
<script type="text/javascript" src="js/overlibmws.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/js/ajaxtags-1.2-beta2.js"></script>
<link rel="stylesheet" type="text/css" href="css/ajaxtags.css" />
<link rel="stylesheet" type="text/css" href="css/displaytag.css" />


</head>
<body>
<c:set var="contextPath" scope="request">${pageContext.request.contextPath}</c:set>



<html:form action="/drop" >



question : <html:text property="question" />
<html:errors property="question" />
<br />





firstCatalog : <html:select property="firstCatalogId">
<html:option value="">select firstCatalog</html:option>
<html:options collection="firstCatalogList"
property="firstcatalogid" labelProperty="catalogname" />
</html:select>
<html:errors property="firstCatalog" />





secondCatalog : <select name="secondCatalogId"
disabled="disabled">
<option value="">select secondCatalog</option>
</select>


<html:submit />
<html:cancel />
</html:form>




<ajax:select baseUrl="/drop.do"
source="firstCatalogId"
target="secondCatalogId"
parameters="fId={firstCatalogId}"
/>
</body>
</html>

  回复  更多评论
  
# re: 在Struts中使用AjaxTags解决连动问题 2006-10-24 18:33 | cdy
package com.compass;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.ajaxtags.helpers.AjaxXmlBuilder;
import org.ajaxtags.servlets.BaseAjaxAction;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;

import com.Dao.CatalogDao;



public class DropAction extends BaseAjaxAction {


public String getXmlContent(
ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response)
throws Exception {
String firstCatalogId = request.getParameter("fId");


CatalogDao catalogDao = new CatalogDao();
List list = catalogDao.getSecondCatalogList(firstCatalogId);
//获得子select

return new AjaxXmlBuilder().addItems(list, "secondcatalogid", "catalogname").toString();
}

}
  回复  更多评论
  
# re: 在Struts中使用AjaxTags解决连动问题 2008-12-26 20:42 | zzl
不行啊  回复  更多评论
  
# re: 在Struts中使用AjaxTags解决连动问题 2008-12-26 20:52 | zzl
这个不行啊,当三级联动时怎办,第一个是通过ACTION ,数据从数据库读入SELECT,第二级是,第一个SELECT 选一个后,跟据取得ID,作为参数,通过AJAX ACTION,从后台查出数据充入第二个SELECT,第二个SELECT 选一个后,跟据取得ID,作为参数,通过AJAX ACTION,从后台查出数据充入第三个SELECT,怎办  回复  更多评论
  
# re: 在Struts中使用AjaxTags解决连动问题 2008-12-26 20:52 | zzl
这个不行啊,当三级联动时怎办,第一个是通过ACTION ,数据从数据库读入SELECT,第二级是,第一个SELECT 选一个后,跟据取得ID,作为参数,通过AJAX ACTION,从后台查出数据充入第二个SELECT,第二个SELECT 选一个后,跟据取得ID,作为参数,通过AJAX ACTION,从后台查出数据充入第三个SELECT,怎办  回复  更多评论
  
# re: 在Struts中使用AjaxTags解决连动问题 2008-12-26 20:52 | zzl
这个不行啊,当三级联动时怎办,第一个是通过ACTION ,数据从数据库读入SELECT,第二级是,第一个SELECT 选一个后,跟据取得ID,作为参数,通过AJAX ACTION,从后台查出数据充入第二个SELECT,第二个SELECT 选一个后,跟据取得ID,作为参数,通过AJAX ACTION,从后台查出数据充入第三个SELECT,怎办  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: