如何做一个级联效果的,城市选择插件

本贴最后更新于 3868 天前,其中的信息可能已经天翻地覆

(一)场景

          老大安排我弄一个城市选择插件,用在公司系统。

(二)准备工作

         最主要的就是数据了,去几个网站逛了一圈,感觉京东的不错,于是就想办法把里面的数据拉下来。京东页面 ,其实很简单,用google浏览器自带的功能,捕捉下http包,查看下request的请求url,就可以看出,每一次请求,按参数返回json,然后组装显示在页面,几个js方法就可以了。然后再后台,服务器启动的时候,将这些数据从数据库查询出来放入内存中,(便于提高速度)。然后每次请求直接从内存中的数据结构拉下来就行。

1、写方法拉京东数据。

<script type="text/javascript">
	$(document).ready(function(){
		//根据市查询县
		function country(z){
			var st="";
			$.getJSON("http://buy.jd.com/purchase/flows/easybuy/FlowService.ashx?&action=GetCountys&Id="+z+"&callback=?", function(data){
				var Are= data.Obj.Areas;
				for (var x in Are){
					st +="insert into qly_bd_region (regionid,regionfid,regiontype,regionname)values('"+Are[x].Id+"' ,'"+z+"','县','"+Are[x].Name+ "');<br/>" ;	
				}
				$("#hh").append(st);
			});
		}
		//根据省id去查询对应的市
			function test(j){
				$.getJSON("http://buy.jd.com/purchase/flows/easybuy/FlowService.ashx?action=GetCitys&Id="+j+"&callback=?", function(data){
					var Areas = data.Obj.Areas;
					//console.log(Areas);
					var str="";
					for(var i in Areas ){
					str +=&quot;insert into qly_bd_region (regionid,regionfid,regiontype,regionname)values('&quot;+Areas[i].Id+&quot;' ,'&quot;+j+&quot;','市','&quot;+Areas[i].Name+ &quot;');&lt;br/&gt;&quot; ;
					setInterval(country(Areas[i].Id),1000);
					
				}
				$(&quot;#divs&quot;).append(str);
			});
		}
		
	
	//这里的i主要表示省id
		for( var i =1;i&lt;32;i++){
			setInterval(test(42),1000);
		}
});</pre> 

以上是查询京东数据,然后直接封装成sql。(这里要注意的是json和jsonp的区别,如果用普通的ajax方法会被服务器拒绝)

2、建数据库表

REGION

3、现在可以写后台处理方法了,封装了数据结构了

helper帮助类

package com.qly.b2b.config;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;

import com.qly.b2b.dao.config.RegionMapper;
import com.qly.b2b.model.config.Region;
import com.qly.b2b.mybatisconn.DbHelper;

public class RegionHelper {
/** 日志组件 **/
private static Logger log = Logger.getLogger(SysConfigHelper.class);

/** 数据缓存是否加载完毕 **/
private static boolean loaded = false;

/** 所有省信息 **/
private static List&lt;Region&gt; provinceList = new ArrayList&lt;Region&gt;();

/** 按省划分的市信息 **/
private static Map&lt;Integer, List&lt;Region&gt;&gt; cityMap = new HashMap&lt;Integer, List&lt;Region&gt;&gt;();

/** 按市划分的区县信息 **/
private static Map&lt;Integer, List&lt;Region&gt;&gt; countyMap = new HashMap&lt;Integer, List&lt;Region&gt;&gt;();

/** 所有地域信息 **/
private static Map&lt;Integer, Region&gt; regionMap = new HashMap&lt;Integer, Region&gt;();

/** 禁止实例化 */
private RegionHelper() {

}

/**
 * 
 * load(进行数据初始化) (这里描述这个方法适用条件 – 可选)
 * 
 * @param force
 *            是否强制加载,用于重新初始化数据 void
 * @exception
 */
private static synchronized void load(boolean force) {
	// 如果非强制初始化(重新初始化),并且已经初始化完毕,返回
	if (loaded &amp;&amp; !force) {
		return;
	}

	log.info(&quot;========================== 加载全国地址静态配置信息到缓存开始 ==========================&quot;);
	loaded = false;
	provinceList.clear();
	cityMap.clear();
	countyMap.clear();
	regionMap.clear();
	
	// 从数据库中获取数据
	List&lt;Region&gt; list = getAllRegion();

	// 将数据加载到缓存
	for (Region region : list) {
        if (&quot;1&quot;.equals(region.getRegiontype())) {
            provinceList.add(region);
        } else if (&quot;2&quot;.equals(region.getRegiontype())) {
            List&lt;Region&gt; cityList = getListFromMap(region.getRegionfid(), cityMap);
            cityList.add(region);
        } else if (&quot;3&quot;.equals(region.getRegiontype())) {
            List&lt;Region&gt; countyList = getListFromMap(region.getRegionfid(), countyMap);
            countyList.add(region);
        }
        
        regionMap.put(region.getRegionid(), region);
    }

	loaded = true;
	log.info(&quot;========================== 加载全国地址静态配置信息到缓存结束 ==========================&quot;);
}

/**
 * getAllRegion(从数据库获取所有地域信息) 
 * (这里描述这个方法适用条件 – 可选) 
 * @return  
 * List&lt;Region&gt; 
 * @exception
 */
private static List&lt;Region&gt; getAllRegion() {
    SqlSession sqlSession = DbHelper.getSqlSession();
    RegionMapper mapper = sqlSession.getMapper(RegionMapper.class);
    List&lt;Region&gt; list = mapper.getAllRegion();
    sqlSession.close();
    return list;
}

/**
 * getListFromMap(根据地域父ID从 Hash map 中获取对应 List) 
 * (这里描述这个方法适用条件 – 可选) 
 * @param regionfid
 * @param map
 * @return  
 * List&lt;Region&gt; 
 * @exception
 */
private static List&lt;Region&gt; getListFromMap(Integer regionfid, Map&lt;Integer, List&lt;Region&gt;&gt; map) {
    if (map.containsKey(regionfid)) {
        return map.get(regionfid);
    } else {
        List&lt;Region&gt; list = new ArrayList&lt;Region&gt;();
        map.put(regionfid, list);
        return list;
    }
}

/**
 * 
 * reload(重新加载数据) (这里描述这个方法适用条件 – 可选) void
 * 
 * @exception
 */
public static void reload() {
	load(true);
}

/**
 * getProvinceList(这里用一句话描述这个方法的作用) 
 * (这里描述这个方法适用条件 – 可选) 
 * @return  
 * List&lt;Region&gt; 
 * @exception
 */
public static List&lt;Region&gt; getProvinceList() {
    if (!loaded) {
        load(false);
    }
    
    return provinceList;
}

/**
 * 根据省id,拿到对应的城市信息
 */
public static List&lt;Region&gt; getCityList(Integer provinceId) {
	if (!loaded) {
	    load(false);
	}

	return cityMap.get(provinceId);
}

/**
 * 根据市id拿到对应的县
 * 
 * @param cityId
 * @return
 */
public static List&lt;Region&gt; getCountyMap(Integer cityId) {
    if (!loaded) {
        load(false);
    }

	return countyMap.get(cityId);
}

/**
 * getRegion(根据地域ID获取地域信息) 
 * (这里描述这个方法适用条件 – 可选) 
 * @param regionId
 * @return  
 * Region 
 * @exception
 */
public static Region getRegion(Integer regionId) {
    if (!loaded) {
        load(false);
    }

    return regionMap.get(regionId);
}

}

controller类

@Controller
@RequestMapping("/region")
public class RegionController extends BaseController {
@RequestMapping(value = &quot;/getallprovince&quot;)
@ResponseBody
public ModelMap getallprovince(HttpServletRequest request, ModelMap modelMap)
		throws Exception {
	List&lt; Region&gt; provincelist = RegionHelper.getProvinceList();
	modelMap.put(&quot;provincelist&quot;, provincelist);
	return modelMap;
}

@RequestMapping(value = &quot;/getcity&quot;)
@ResponseBody
public ModelMap getcity(HttpServletRequest request, ModelMap modelMap)
		throws Exception {
	List&lt; Region&gt; citylist = RegionHelper.getCityList(Integer.parseInt(request.getParameter(&quot;id&quot;)));
	modelMap.put(&quot;citylist&quot;, citylist);
	return modelMap;
}

@RequestMapping(value = &quot;/getcounty&quot;)
@ResponseBody
public ModelMap getcounty(HttpServletRequest request, ModelMap modelMap)
		throws Exception {
	List&lt; Region&gt; countylist = RegionHelper.getCountyMap(Integer.parseInt(request.getParameter(&quot;id&quot;)));
	modelMap.put(&quot;countylist&quot;, countylist);
	return modelMap;
}

}

4、处理前台js展现

$(document).ready(function(){
	//获得省列表,初始化第一个 select
	$.getJSON(basepath+"/region/getallprovince", function(data){
	  setOptions("province", data.provincelist);
	});
});

//获取城市列表
function getCitys(){
setAddress();

var cityid = $(&quot;#province&quot;).find(&quot;option:selected&quot;).val();
if (cityid == &quot;&quot;)
{
	clearSelect(&quot;city&quot;);
	return;
}
$.getJSON(basepath+&quot;/region/getcity&quot;,{id:cityid}, function(data){
	 setOptions(&quot;city&quot;, data.citylist);
	});

  //清空地区列表
  clearSelect(&quot;county&quot;);

// });
}

//获取地区列表
function getAreas(){
setAddress();
var countyid = $("#city").find("option:selected").val();
if (countyid == "")
{
clearSelect("county");
return;
}
$.getJSON(basepath+"/region/getcounty",{id:countyid}, function(data){
setOptions("county", data.countylist);
});
}

//清空下拉列表
function clearSelect(id){
$("#" + id).empty() ;
$("#" + id).append("<option value=''>请选择</option>");
}

//将数据放到指定 select 中
function setOptions(id, datas) {
$("#" + id).empty() ;
$("#" + id).append("<option value=''>请选择</option>");
for (var i in datas )
{
$("#" + id).append("<option value='" + datas[i].regionid + "'>" + datas[i].regionname + "</option>");
}
}

function setAddress(){
var address = getOptionName("province") + getOptionName("city") + getOptionName("county");
$("#address1").html(address);
var address1 = $("#address1").text();
$("#provinceaddress").val(address1);
}

function getOptionName(id) {
if($("#" + id).find("option:selected").val() != ""){
return $("#" + id).find("option:selected").html();
}

return &quot;&quot;;

}

<select name="province" id="province" onchange="getCitys()">
<option value=''>请选择</option>
</select> <select name="city" id="city" onchange="getAreas()">
<option value=''>请选择</option>
</select> <select name="county" id="county"
onchange="setAddress()">
<option value=''>请选择</option>
</select>

<span id="address1"></span></span>

5、到此为止,一个js城市选择的插件就ok了

(三)技术点

      主要是封装数据结构,和获取数据。

(四)检查数据

SELECT a.regionid,a.regionname, b.regionid,b.regionname FROM qly_bd_region a LEFT JOIN qly_bd_region b ON b.regionfid = a.regionid WHERE b.regionid IS  NULL AND a.regiontype IN (1,2)

这条sql语句可以帮助你,数据是否正确。主要用了左连接,然后id和fid就可以找出数据是否缺失

  • JavaScript

    JavaScript 一种动态类型、弱类型、基于原型的直译式脚本语言,内置支持类型。它的解释器被称为 JavaScript 引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在 HTML 网页上使用,用来给 HTML 网页增加动态功能。

    710 引用 • 1173 回帖 • 175 关注
  • jQuery

    jQuery 是一套跨浏览器的 JavaScript 库,强化 HTML 与 JavaScript 之间的操作。由 John Resig 在 2006 年 1 月的 BarCamp NYC 上释出第一个版本。全球约有 28% 的网站使用 jQuery,是非常受欢迎的 JavaScript 库。

    63 引用 • 134 回帖 • 745 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • Caddy

    Caddy 是一款默认自动启用 HTTPS 的 HTTP/2 Web 服务器。

    10 引用 • 54 回帖 • 130 关注
  • 音乐

    你听到信仰的声音了么?

    59 引用 • 509 回帖
  • PHP

    PHP(Hypertext Preprocessor)是一种开源脚本语言。语法吸收了 C 语言、 Java 和 Perl 的特点,主要适用于 Web 开发领域,据说是世界上最好的编程语言。

    164 引用 • 407 回帖 • 526 关注
  • RIP

    愿逝者安息!

    8 引用 • 92 回帖 • 293 关注
  • MySQL

    MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是最流行的关系型数据库管理系统之一。

    675 引用 • 535 回帖
  • etcd

    etcd 是一个分布式、高可用的 key-value 数据存储,专门用于在分布式系统中保存关键数据。

    5 引用 • 26 回帖 • 492 关注
  • Pipe

    Pipe 是一款小而美的开源博客平台。Pipe 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    131 引用 • 1114 回帖 • 150 关注
  • Oracle

    Oracle(甲骨文)公司,全称甲骨文股份有限公司(甲骨文软件系统有限公司),是全球最大的企业级软件公司,总部位于美国加利福尼亚州的红木滩。1989 年正式进入中国市场。2013 年,甲骨文已超越 IBM,成为继 Microsoft 后全球第二大软件公司。

    103 引用 • 126 回帖 • 453 关注
  • Tomcat

    Tomcat 最早是由 Sun Microsystems 开发的一个 Servlet 容器,在 1999 年被捐献给 ASF(Apache Software Foundation),隶属于 Jakarta 项目,现在已经独立为一个顶级项目。Tomcat 主要实现了 JavaEE 中的 Servlet、JSP 规范,同时也提供 HTTP 服务,是市场上非常流行的 Java Web 容器。

    162 引用 • 529 回帖
  • Q&A

    提问之前请先看《提问的智慧》,好的问题比好的答案更有价值。

    6522 引用 • 29305 回帖 • 248 关注
  • Webswing

    Webswing 是一个能将任何 Swing 应用通过纯 HTML5 运行在浏览器中的 Web 服务器,详细介绍请看 将 Java Swing 应用变成 Web 应用

    1 引用 • 15 回帖 • 635 关注
  • Hprose

    Hprose 是一款先进的轻量级、跨语言、跨平台、无侵入式、高性能动态远程对象调用引擎库。它不仅简单易用,而且功能强大。你无需专门学习,只需看上几眼,就能用它轻松构建分布式应用系统。

    9 引用 • 17 回帖 • 597 关注
  • 一些有用的避坑指南。

    69 引用 • 93 回帖
  • C++

    C++ 是在 C 语言的基础上开发的一种通用编程语言,应用广泛。C++ 支持多种编程范式,面向对象编程、泛型编程和过程化编程。

    106 引用 • 152 回帖 • 1 关注
  • 黑曜石

    黑曜石是一款强大的知识库工具,支持本地 Markdown 文件编辑,支持双向链接和关系图。

    A second brain, for you, forever.

    10 引用 • 85 回帖
  • 阿里云

    阿里云是阿里巴巴集团旗下公司,是全球领先的云计算及人工智能科技公司。提供云服务器、云数据库、云安全等云计算服务,以及大数据、人工智能服务、精准定制基于场景的行业解决方案。

    89 引用 • 345 回帖 • 1 关注
  • Ant-Design

    Ant Design 是服务于企业级产品的设计体系,基于确定和自然的设计价值观上的模块化解决方案,让设计者和开发者专注于更好的用户体验。

    17 引用 • 23 回帖
  • 创造

    你创造的作品可能会帮助到很多人,如果是开源项目的话就更赞了!

    172 引用 • 990 回帖
  • Android

    Android 是一种以 Linux 为基础的开放源码操作系统,主要使用于便携设备。2005 年由 Google 收购注资,并拉拢多家制造商组成开放手机联盟开发改良,逐渐扩展到到平板电脑及其他领域上。

    333 引用 • 323 回帖 • 70 关注
  • 服务

    提供一个服务绝不仅仅是简单的把硬件和软件累加在一起,它包括了服务的可靠性、服务的标准化、以及对服务的监控、维护、技术支持等。

    41 引用 • 24 回帖 • 4 关注
  • InfluxDB

    InfluxDB 是一个开源的没有外部依赖的时间序列数据库。适用于记录度量,事件及实时分析。

    2 引用 • 54 关注
  • ZooKeeper

    ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 HBase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

    59 引用 • 29 回帖 • 15 关注
  • Thymeleaf

    Thymeleaf 是一款用于渲染 XML/XHTML/HTML5 内容的模板引擎。类似 Velocity、 FreeMarker 等,它也可以轻易的与 Spring 等 Web 框架进行集成作为 Web 应用的模板引擎。与其它模板引擎相比,Thymeleaf 最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个 Web 应用。

    11 引用 • 19 回帖 • 317 关注
  • 链书

    链书(Chainbook)是 B3log 开源社区提供的区块链纸质书交易平台,通过 B3T 实现共享激励与价值链。可将你的闲置书籍上架到链书,我们共同构建这个全新的交易平台,让闲置书籍继续发挥它的价值。

    链书社

    链书目前已经下线,也许以后还有计划重制上线。

    14 引用 • 257 回帖
  • API

    应用程序编程接口(Application Programming Interface)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。

    76 引用 • 421 回帖
  • 星云链

    星云链是一个开源公链,业内简单的将其称为区块链上的谷歌。其实它不仅仅是区块链搜索引擎,一个公链的所有功能,它基本都有,比如你可以用它来开发部署你的去中心化的 APP,你可以在上面编写智能合约,发送交易等等。3 分钟快速接入星云链 (NAS) 测试网

    3 引用 • 16 回帖 • 5 关注
  • LaTeX

    LaTeX(音译“拉泰赫”)是一种基于 ΤΕΧ 的排版系统,由美国计算机学家莱斯利·兰伯特(Leslie Lamport)在 20 世纪 80 年代初期开发,利用这种格式,即使使用者没有排版和程序设计的知识也可以充分发挥由 TeX 所提供的强大功能,能在几天,甚至几小时内生成很多具有书籍质量的印刷品。对于生成复杂表格和数学公式,这一点表现得尤为突出。因此它非常适用于生成高印刷质量的科技和数学类文档。

    9 引用 • 32 回帖 • 168 关注