ExtJS(三)--Ajax实现省份城市联动

来源:互联网 发布:wind数据库有免费版吗 编辑:程序博客网 时间:2024/06/05 04:50

        今天学习了Ajax技术,刚刚做了一个省份-城市联动的Ajax应用示例。可能很多人都已经写过了,也是一个比较简单的例子,在这里分享出来大家共同学习交流一下。希望能给到那些像我一样的菜鸟程序员参考一点帮助吧!

效果截图:

       省份-城市联动就是当你在省份下拉列表框选择一个省份的时候,旁边的城市下拉列表框就会动态地生成该省份对应的城市列表。如:省份是广东,则城市的下拉框对应显示广州、茂名、梅州等城市;省份是北京,城市的下拉列表框则显示海淀、朝阳等城市。因为我本人主要从事JavaEE的相关开发,因此这个小应用示例也就写专业一点啦!使用model2的两层架构。因为是一个小应用示例,因此没有跟数据库打交道,数据就都保存到内存中。

       好了,我讲的废话太多了,下面开始叙述省份-城市联动的开发过程。

  实施步骤:

  1. 编写后台service层。在三层架构中,层与层之间使用接口连接,因此要编写service接口。
  2. 编写后台web层的控制器servlet(省份的控制器和城市的控制器),主要负责加载后台省份和城市的数据,并将其传输到前台页面。
  3. 编写前台html静态页面,负责给用户显示数据。
  4. 编写javascript脚本程序,处理用户选择省份的请求操作。

整个应用的流程图:

 

(一)service层的接口代码

package cn.itcast.ajax.service;import java.util.List;public interface ProvinceCityService {/** * 返回省份数据集合 * @return */List<String> loadProvince();/** * 根据省份返回城市的集合 * @param province * @return */List<String> loadCity(String province);}

实现接口中定义的功能

package cn.itcast.ajax.service.impl;import java.util.ArrayList;import java.util.Arrays;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import cn.itcast.ajax.service.ProvinceCityService;public class ProvinceCityServiceImpl implements ProvinceCityService {/* * 因为是一个省份与城市下拉的ajax小应用实例,因此不与数据库交道了,使用map存储数据 (non-Javadoc) *  * @see cn.itcast.ajax.service.ProvinceService#loadProvince() */private Map<String, List<String>> provinceMap = new HashMap<String, List<String>>();String[] gdCity = new String[] { "广州", "汕头", "梅州", "茂名" };String[] bjCity = new String[] { "海淀", "朝阳", "中关村" };public ProvinceCityServiceImpl() {provinceMap.put("广东", Arrays.asList(gdCity));provinceMap.put("北京", Arrays.asList(bjCity));}@Overridepublic List<String> loadProvince() {List<String> provinces = new ArrayList<String>();Set<String> keySet = provinceMap.keySet();for (Iterator<String> iterator = keySet.iterator(); iterator.hasNext();) {String province = iterator.next();provinces.add(province);}return provinces;}@Overridepublic List<String> loadCity(String province) {return provinceMap.get(province);}}

(二)控制层Servlet代码

因为需要对省份和城市分开不同处理,所以使用ProvinceServlet和CityServlet两个servlet控制器

ProvinceServlet:

package cn.itcast.ajax.servlet;import java.io.IOException;import java.util.List;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import cn.itcast.ajax.service.ProvinceCityService;import cn.itcast.ajax.service.impl.ProvinceCityServiceImpl;/** * Servlet implementation class ProvinceServlet */public class ProvinceServlet extends HttpServlet {private static final long serialVersionUID = 1L;private ProvinceCityService provinceService = new ProvinceCityServiceImpl();protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding("UTF-8");List<String> provinces = provinceService.loadProvince();StringBuffer sb = new StringBuffer();sb.append("[");for (int i =0;i<provinces.size();i++) {String province = provinces.get(i);sb.append("\"").append(province).append("\"");// 如果i的值小于list的长度的时候就添加一个逗号,确保最后一个不会添加多一个逗号if (i < provinces.size() - 1) {sb.append(",");}}sb.append("]");response.setHeader("Content-Type", "text/html; charset=UTF-8");response.getWriter().println(sb.toString());}protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}public void testData() {List<String> provinces = provinceService.loadProvince();StringBuffer sb = new StringBuffer();sb.append("[");for (int i =0;i<provinces.size();i++) {String province = provinces.get(i);sb.append("\"").append(province);// 如果i的值小于list的长度的时候就添加一个逗号,确保最后一个不会添加多一个逗号if (i < provinces.size() - 1) {sb.append(",");}}sb.append("]");System.out.println(sb.toString());}}

CityServlet:

package cn.itcast.ajax.servlet;import java.io.IOException;import java.util.Iterator;import java.util.List;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import cn.itcast.ajax.service.ProvinceCityService;import cn.itcast.ajax.service.impl.ProvinceCityServiceImpl;/** * Servlet implementation class CityServlet */public class CityServlet extends HttpServlet {private static final long serialVersionUID = 1L;private ProvinceCityService cityService = new ProvinceCityServiceImpl();protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {String province = request.getParameter("province");List<String> citys = cityService.loadCity(province);StringBuffer sb = new StringBuffer("[");for (int i = 0; i < citys.size(); i++) {sb.append("\"").append(citys.get(i)).append("\"");if (i < citys.size() - 1) {sb.append(",");}}sb.append("]");response.setHeader("Content-Type", "text/html; charset=UTF-8");response.getWriter().println(sb.toString());response.getWriter().close();}protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}}

(三)前台html静态页面province_city.html

这里要注意一点,省份的数据需要首先加载出来,添加到省份的下拉列表框中,因此在这个页面载入的时候就必须从后台加载数据出来。

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>省份-城市下拉联动</title><script type="text/javascript" src="province_city.js"></script></head><body>请选择省份:<select id="province" onchange="provinceChange()"></select>请选择城市:<select id="city"></select></body></html>


(四)javascript脚本程序province_city.js

// 初始化XMLHttpRequest对象function createXmlHttpRequest() {var xmlhttp = null;try {// Firefox, Opera 8.0+, Safarixmlhttp = new XMLHttpRequest();} catch (e) {// IE7.0以下的浏览器以ActiveX组件的方式来创建XMLHttpRequest对象var MSXML = [ 'MSXML2.XMLHTTP.6.0', 'MSXML2.XMLHTTP.5.0','MSXML2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP','Microsoft.XMLHTTP' ];for ( var i = 0; i < MSXML.length; i++) {try {xmlhttp = new ActiveXObject(MSXML[i]);break;} catch (e) {}}}// 返回对象return xmlhttp;}window.onload = function() {loadProvinces();};// 加载省份数据function loadProvinces() {var province = document.getElementById("province");//alert("sdhgjf");// 创建XMLHttpRequest对象var xhr = createXmlHttpRequest();// 发送请求xhr.open("get", "ProvinceServlet", true);xhr.send(null);// 接收服务器端传递回来的数据xhr.onreadystatechange = function() {// 判断数据是否处理完全if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 304)) {var provinces = eval("(" + xhr.responseText + ")");//alert(provinces);// 处理返回来的字符串var s = "<option>请选择</option>";for ( var i = 0; i < provinces.length; i++) {s+="<option>"+provinces[i]+"</option>";}province.innerHTML = s;}};}// 省份选择发生改变的时候的处理函数function provinceChange() {// 获取当前选中的省份var provinces = document.getElementById("province");var province = provinces.options[provinces.selectedIndex].value;var city = document.getElementById("city");//alert(province);var xhr = createXmlHttpRequest();xhr.open("post", "CityServlet", true);// 以post方式发送请求的时候需要设置请求的方式xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");xhr.send("province="+province);// 处理服务器端返回来的数据xhr.onreadystatechange = function() {// 判断数据是否处理完全if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 304)) {var citys = eval("(" + xhr.responseText + ")");//alert(provinces);// 处理返回来的字符串var s = "<option>--</option>";// 创建一个option子元素for ( var i = 0; i < citys.length; i++) {// 将返回来的城市数据添加到option元素中s+="<option>"+citys[i]+"</option>";}city.innerHTML = s;}};}

 

示例源代码下载

 

       因为这个小应用纯粹用于学习总结,因此写了比较多的注释,但是总体还算比较易于阅读的。





 

 

原创粉丝点击