当前所做的项目,关于数据库设计的时候有点小意思,表A是三个联合主键,key1,key2,key3,表B是四个联合主键 key1,key2,key3,key4,其中表B的联合外键关联表A对应的联合主键,其实这种情况是很多的,比如常见的 省、市、区 三级菜单。这样一来,对表B做新增的时候 就需要几个小步骤:
①:界面初始化,返回下拉列表 key1(distinct)、key2(只赋值初始值)、key3(只赋值初始值)
②:界面勾选key1,触发chang事件,采用getJson 方式将参数key1的值发送到Action中 ,同时设置下拉列表b 的内容为空,$("#b").html('');
控制器做处理后,返回 key2的集合
③:界面的回调函数中,给下拉列表b 用append 的方式加入 value 值 和 文本值
④:界面勾选key2,触发change事件,采用getJson 方式将参数key1、key2 的值发送到Action中,同样设置下拉列表c的内容为空,$("#c").html('');
控制器做处理后,返回key3的集合
⑤:界面回调函数中,给下拉列表c 用append的方式加入 value 值 和文本值
⑥:判断key4 是否在表B中存在,不存在,插入数据,返回提示
从着手项目以来,最开始总想用代码来说明,虽然最后是实现了功能,但回过头看起来,简直是惨不忍睹,实在是有删除从写的冲动,越来越久,才发现,先考虑清楚逻辑,就是深度思考是第一步,虽然说起来很容易,往往实践起来很难
--主表TMain 从表TMinor use TestBook alter table TMinor add constraint Tminor_fk foreign key(Key1,Key2,Key3) references TMain(Key1,Key2,Key3)
第一步: 将三级联动的下拉列表封装到一个类中
public class TMainResult { /// <summary> /// 一级下拉框 /// </summary> public string Key1 { get; set; } /// <summary> /// 二级下拉框 /// </summary> public string Key2 { get; set; } /// <summary> /// 三级下拉框 /// </summary> public string Key3 { get; set; } }
第二步:在控制器中设置列表值,并在前台展示
public ActionResult Index() { //绑定Key1 //GetKey1() 得到表中 key1栏位集合 ViewBag.List_Key1 = new SelectList(dbhelper.GetKey1.ToList(), "Key1", "Key1").AsEnumerable(); //Key2、Key3 赋空值 List<ThreeDrop> selectlist = new List<ThreeDrop>(); ViewBag.List_Key2 = new SelectList(selectlist, "Key2", "Key2").AsEnumerable(); ViewBag.List_Key3 = new SelectList(selectlist, "Key3", "Key3").AsEnumerable(); return View(); }
<div> @using (Html.BeginForm("Index")) { <label>一级菜单(省份)</label> @Html.DropDownList("Key1", ViewBag.List_Key1 as IEnumerable<SelectListItem>,'请选择') <p></p> <label>二级菜单(地级市)</label> @Html.DropDownList("Key2",ViewBag.List_Key2 as IEnumerable<SelectListItem>,'请选择') <p></p> <label>三级菜单(区、县)</label> @Html.DropDownListFor(m=>m.Key3,ViewBag.List_Key3 as IEnumerable<SelectListItem>,'请选择') } </div>
第三步: 后台写好返回的数据
//實現二級連動 public JsonResult GetKey2Bykey1(string key1) { List<ThreeDrop> ConfigTypelist = dbhelper.GetKey2(key1).ToList(); return Json(ConfigTypelist, JsonRequestBehavior.AllowGet); } //實現三級聯動 public JsonResult GetKey3Bykey2(string key1, string key2) { List<ThreeDrop> ConfigMSTlist = dbhelper.GetKey3(key1, key2).ToList(); return Json(ConfigMSTlist, JsonRequestBehavior.AllowGet); }
第四步: 前台发送Ajax请求,并解析后台返回的数据
<script> $(function () { //一级联动 $("#Key1").change(function () { var url = "/Test/GetKey2/?Key1=" + $("#Key1").val() + ""; $.getJSON(url, function (data) { $("#Key2").html(''); $("#Key2").append("<option value=''>请选择</option>"); $.each(data, function (i,item) { $("#Key2").append("<option value='"+item.Key2+"'>"+item.Key2+"</option>"); }) }); }) //二级联动 $("#Key2").change(function () { var url = "/Text/GetKey3/?Key1="+$("#Key1").val()+"&&Key2="+$("#Key2").val()+""; $.getJSON(url, function (data) { $("#Key3").html(''); $("#Key3").append("<option value=''>请选择</option>"); $.each(data, function () { $("#Key3").append("<option value='"+$("#Key3")+"'>'"+$("#Key3")+"'</option>"); }) }) }) }) </script>
这样以来,我们前台就只需要判断,key1 和key2 的value值不能为空 就可以得到一组正确三级数据值,那么在后台接收的时候,就通过封装一个新增 model实体类 直接传值到后台进行处理,至于先判断Key4是否在B表中是否有重复值,这就是不是重点了,总之大致思路就是这样。
为什么第一次加载界面的二三级下拉列表值为空?
因为联动是 触发change() 事件,只有鼠标点选了下拉列表才会触发,如果上来二三级下拉列表也绑定,那么点选一后,二自动变换,此时再去点选三,就不是二联动过去