你的位置:首页 > ASP.net教程

[ASP.net教程]MVC地区多级联动扩展实现(非递归形式)


MVC前台界面调用方式如下:

 @Html.AreaDropDownList("areaCode", areaCode, 3, string.Empty)

参数说明:

 第一个参数控件的名称;
 第二个参数选中的地区编码;
 第三个参数地区层级;
 第四个参数根级地区;

地区数据库表设计如下:

下拉列表的扩展:

 1  #region 下拉列表 2  3     /// <summary> 4     /// 联动下拉列表 5     /// </summary> 6     /// <param name="htmlHelper">被扩展的HtmlHelper实例</param> 7     /// <param name="expression">获取数据集合</param> 8     /// <param name="level">显示多少级</param> 9     /// <param name="defaultValue">TProperty类型的默认值(如string默认值为"")</param>10     /// <param name="rootItems">获取根级列表数据</param>11     /// <param name="getParentID">获取列表项的ParentID方法</param>12     /// <param name="getChildItems">获取子级列表数据集合方法</param>13     /// <param name="getChildSelectDataUrl">获取子级列表数据的远程地址</param>14     /// <returns>html代码</returns>15     public static MvcHtmlString LinkageDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, TProperty defaultValue, int level, Dictionary<TProperty, string> rootItems,Func<TProperty, TProperty> getParentID, Func<TProperty, Dictionary<TProperty, string>> getChildItems,string getChildSelectDataUrl,string optionLabel = "请选择")16     {17       ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);18 19       return LinkageDropDownList(htmlHelper, ExpressionHelper.GetExpressionText(expression), (TProperty)metadata.Model, defaultValue, level, rootItems, getParentID,getChildItems,getChildSelectDataUrl,optionLabel);20     }21 22 23     /// <summary>24     /// 联动下拉列表25     /// </summary>26     /// <param name="htmlHelper">被扩展的HtmlHelper实例</param>27     /// <param name="level">显示多少级</param>28     /// <param name="defaultValue">TProperty类型的默认值(如string默认值为"")</param>29     /// <param name="name">下拉列表表单项名</param>30     /// <param name="selectedValue">当前选中值</param>31     /// <param name="rootItems">获取根级列表数据</param>32     /// <param name="getParentId">获取列表项的ParentID方法</param>33     /// <param name="getChildItems">获取子级列表数据集合方法</param>34     /// <param name="getChildSelectDataUrl">获取子级列表数据的远程地址</param>35     /// <returns>html代码</returns>36     public static MvcHtmlString LinkageDropDownList<TProperty>(this HtmlHelper htmlHelper, string name, TProperty selectedValue,TProperty defaultValue, int level, Dictionary<TProperty, string> rootItems, Func<TProperty, TProperty> getParentId, Func<TProperty, Dictionary<TProperty, string>> getChildItems, string getChildSelectDataUrl, string optionLabel = "请选择")37     {38       string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);39       //select data init40       Stack<Dictionary<TProperty, string>> stack = new Stack<Dictionary<TProperty, string>>();41 42       //如果有选中的值,则查找其所在列表前面的所有列表43       IList<TProperty> selectedValues = new List<TProperty>();44       if (selectedValue != null && !selectedValue.Equals(defaultValue))45       {46         TProperty itemId = selectedValue;47         TProperty parentItemId = getParentId(itemId);48         while (!itemId.Equals(defaultValue) && !parentItemId.Equals(defaultValue))49         {50           stack.Push(getChildItems(parentItemId));51           selectedValues.Add(itemId);52           itemId = parentItemId;53           parentItemId = getParentId(itemId);54         }55         if (rootItems.Count() > 0)56         {57           TProperty rootId = getParentId(rootItems.First().Key);58           if (!itemId.Equals(rootId))59           {60             stack.Push(rootItems);61             selectedValues.Add(itemId);62           }63         }64       }65       else66       {67         TProperty rootItemID = rootItems.Select(n => n.Key).FirstOrDefault();68         stack.Push(rootItems);69       }70 71       //生成标签72       TagBuilder containerBuilder = new TagBuilder("span");73       containerBuilder.MergeAttribute("plugin", "linkageDropDownList");74       var data = new Dictionary<string, object>();75       data.TryAdd("GetChildSelectDataUrl", getChildSelectDataUrl);76       data.TryAdd("ControlName", name);77       data.TryAdd("Level", level);78       data.TryAdd("OptionLabel", optionLabel);79       data.TryAdd("DefaultValue", defaultValue.ToString());80       containerBuilder.MergeAttribute("data", Json.Encode(data));81       int currentIndex = 0;82       while (stack.Count > 0)83       {84         Dictionary<TProperty, string> dictionary = stack.Pop();85         IEnumerable<SelectListItem> selectList = dictionary.Select(n => new SelectListItem() { Selected = selectedValues.Contains(n.Key), Text = n.Value, Value = n.Key.ToString() });86         containerBuilder.InnerHtml += "\r\n" + htmlHelper.DropDownList(string.Format("{0}_{1}", name, currentIndex), selectList,87                 optionLabel, new { @class = "tn-dropdownlist" });88         currentIndex++;89       }90       containerBuilder.InnerHtml += "\r\n" + htmlHelper.Hidden(name);91       return MvcHtmlString.Create(containerBuilder.ToString());92     }93 94     #endregion

View Code

 

对外的调用的实现:

 1     /// <summary> 2     /// 地区下拉列表 3     /// </summary> 4     /// <param name="htmlHelper">被扩展的htmlHelper实例</param> 5     /// <param name="expression">选择实体中类别属性的lamda表达式</param> 6     /// <param name="areaLevel">地区层级(默认取站点地区配置)</param> 7     /// <param name="rootAreaCode">根级地区(默认取站点地区配置)</param> 8     public static MvcHtmlString AreaDropDownListFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, string>> expression, int? areaLevel = null, string rootAreaCode = null)11     {12       string getChildAreasUrl = "/Channel/GetChildAreas";//获取子地区的远程地址,(AreaCode,name)的JSON数据13       if (areaLevel == null)15       {16         areaLevel = 0;//区域设置级别,可以作为配置文件获取17       }18       return htmlHelper.LinkageDropDownListFor<TModel, string>(expression, string.Empty, areaLevel.Value, 获取根级区域的(AreaCode,name)键值对,获取当前选中区域的父区域, 获取当前的子区域, getChildAreasUrl);21     }22 23     /// <summary>24     /// 地区下拉列表25     /// </summary>26     /// <param name="htmlHelper">被扩展的htmlHelper实例</param>27     /// <param name="name">控件name属性</param>28     /// <param name="name">选中的地区编码</param>29     /// <param name="areaLevel">地区层级(默认取站点配置)</param>30     /// <param name="rootAreaCode">根级地区(默认取站点地区配置)</param>31     public static MvcHtmlString AreaDropDownList(this HtmlHelper htmlHelper, string name, string value, int? areaLevel = null, string rootAreaCode = null)32     {33       string getChildAreasUrl = "/Channel/GetChildAreas";//获取子地区的远程地址,(AreaCode,name)的JSON数据34       if (areaLevel == null)36       {37         areaLevel = 0;//区域设置级别,可以作为配置文件获取38       }39       return htmlHelper.LinkageDropDownList<string>(name, value, string.Empty, areaLevel.Value, 获取根级区域的(AreaCode,name)键值对, 获取当前选中区域的父区域, 获取选中地区当前的子区域, getChildAreasUrl);42     }