有时候,我们的网页需要级联菜单或者级联下拉框,比如在选择一个省市县的时候,我们必须让下拉框为联动下拉框,才能获取该省份下的该市下的该县!下面我用一个例子来演示下在MVC中如何用ajax技术制作联动下拉框!
1. 首先我们在view里写入两个下拉框:
1 <div class="editor-field"> 2 3 4 @Html.DropDownList("fathernodeid") 5 6 7 @Html.DropDownList("nodeid") 8 9 10 </div>
一个id和name都为fathernodeid的下拉框和一个id和name都为nodeid的下拉框,我们接下来要做的就是改变fathernodeid 下拉框的选项后nodeid下拉框的选项也跟着改变,这里的改变选项是无刷新的,因为我们要用ajax异步加载这些选项!
Ok,我们去创建个JavaScript脚本文件TypeLinkage.js,代码如下:
1 //类别联动js脚本 2 3 4 $(document).ready(function() { 5 6 7 $("#fathernodeid").change(function() { 8 9 10 GetChildrenTreeList(); //获取子选项 11 12 13 }); 14 15 16 }); 17 18 19 20 21 22 function GetChildrenTreeList() { 23 24 25 var url = "/TheTree/GetChildrenTreeList/" + $("#fathernodeid").val(); 26 27 28 $.getJSON( 29 30 31 url, function(data) { 32 33 34 $("#nodeid").empty(); //清空原来的选项 35 36 37 $.each(data,function(i, item) { 38 39 40 $("<option></option>").val(item["ID"]).text(item["Nodename"]).appendTo("#nodeid"); 41 42 43 }); 44 45 46 }); 47 48 };
因为我的view用了布局页,所以我们直接将js引用到布局页中即可,在这之前我们首先要把js加入到BundleConfig.cs中,他是为我们集中化管理js脚本和css样式表的一个文件,现在我们把刚才写好的联动脚本也放进去并起个名字为~/bundles/TypeLinkage如下:
1 bundles.Add(newScriptBundle("~/bundles/TypeLinkage").Include( 2 "~/Scripts/TypeLinkage.js" 3 ));
2.现在我们在布局页中设置一个占位,这样引用此布局页的页面就可以为我们留出来一个空间让我们写自己的代码了,布局页中随便地方加入 @RenderSection("scripts", required: false)
第一个参数为占位符名字,第二个参数是设置引用此页面的页面必须填充占位符也可以选择不填充,这里我们选择可以选择不填充。
现在来到我们的view层代码;来填充我们的占位符,如下:
1 @section Scripts { 2 3 4 @Scripts.Render("~/bundles/jqueryval") 5 6 7 @Scripts.Render("~/bundles/TypeLinkage") 8 9 10 }
我是在页面最底部填充的占位符!
3.现在我们去写控制器中的方法吧:
1 ///<summary> 2 3 4 ///ajax获取json数据的子类型列表 5 6 7 ///</summary> 8 9 10 ///<paramname="id"></param> 11 12 13 ///<returns></returns> 14 15 16 public JsonResult GetChildrenTreeList(intid) 17 18 19 { 20 21 22 List<TheTree>treelist = db.TheTrees.Where(e => e.TheFatherNode == id).ToList(); 23 24 25 return Json(treelist, JsonRequestBehavior.AllowGet); 26 27 28 }
JsonResult 是ActionResult的一个子类,所以我们可以返回这种类型的视图。
代码很简单,就是根据第一个下拉框的id获取数据库中父节点id==参数id的项的集合然后用json的方式返回给视图,这里要注意的是,因为页面有缓存,所以我们要在控制器类上加上取消缓存的特性来声明该类中的所有方法均不缓存数据,特性如下:
1 [OutputCache(Location = OutputCacheLocation.None,NoStore = true)] //清除缓存
Ok,现在可以运行我们的程序看效果啦……