省市县乡村 动态级联加载控件AreaRender(一)

最近在做项目的时候需要对用户的籍贯和所在地的加载问题,以前也遇到过这个问题,只是临时应付了一下.

最近觉得这个以后还要用到,所以就重新整理了思路,写出一个尽量通用的全国区划动态加载的扩展方法。

首先分析一下需求:加载某个用户的信息时,需要将该用户的籍贯和所在地展示出来,还可以让其修改。

思路:初次加载时,将地址信息隐藏起来,而后根据隐藏的值逐级给select赋值。

初始化阶段:

1.首先加载省份信息;

2.将隐藏域中省份的值赋给select,在此根据隐藏域中的值加载市的信息;

3.一次类推,直到加载到村,或者没有默认值为止。

修改阶段:

1.将所有的select的选中的值赋值给隐藏域;

2.加载下一级数据。 

接下来我们自上往下讲解代码编写过程。

1.新建asp.net mvc 3 的项目

2.在index.cshtml文件中调用控件

@model List<DynamicArea.Models.ChinaArea>
@using DynamicArea.Helpers
@{
    ViewBag.Title = "测试地区的级联加载";
    Layout = "~/Views/Shared/_Layout.cshtml";
    <script src="http://www.cnblogs.com/Scripts/InitNextLevle.js" type="text/javascript"></script>
    <script src="http://www.cnblogs.com/Scripts/AddNextLevel.js" type="text/javascript"></script>
    <script src="http://www.cnblogs.com/Scripts/SetValue.js" type="text/javascript"></script>
    <script src="http://www.cnblogs.com/Scripts/AddProvince.js" type="text/javascript"></script>
}
@using (Html.BeginForm("Save", "Home"))
{
    @Html.AreaRender(ViewBag.ds1 as Dictionary<string, string>, ViewBag.provinceUrl as string, ViewBag.nextUrl as string)
    @Html.AreaRender(ViewBag.ds2 as Dictionary<string, string>, ViewBag.provinceUrl as string, ViewBag.nextUrl as string)
}

大家可以看到,我们需要提供三个参数,从中也可以看到参数的类型:

ViewBag.ds1 as Dictionary<string, string>, ViewBag.provinceUrl as string, ViewBag.nextUrl as string
接下来看控制器中如何提供这些参数

    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            //新疆维吾尔自治区:650000000000
            //乌鲁木齐市      :650100000000
            //天山区          :650102000000
            //燕儿窝街道      :650102002000
            //燕儿窝南社区居委会:650102002002
            Dictionary<string, string> ds1 = new Dictionary<string, string>();
            ds1.Add("pro.id", "650000000000");
            ds1.Add("cit.id", "650100000000");
            ds1.Add("cou.id", "650102000000");
            ds1.Add("tow.id", "650102002000");
            ds1.Add("vil.id", "650102002002");
            ds1.Add("pro.name", "新疆维吾尔自治区");
            ds1.Add("cit.name", "乌鲁木齐市");
            ds1.Add("cou.name", "天山区");
            ds1.Add("tow.name", "燕儿窝街道");
            ds1.Add("vil.name", "燕儿窝南社区居委会");
            ViewBag.ds1 = ds1;
            ViewBag.ds2 = ds1;
            ViewBag.provinceUrl = "/Home/GetProvinces";
            ViewBag.nextUrl = "/Home/GetNextLevel";
            return View();
        }

        [HttpPost]
        public ActionResult Save(FormCollection fc)
        {
            Area area = new Area();
            UpdateModel(area, fc);
            return Index();
        }

        [HttpPost]
        public JsonResult GetProvinces()
        {
            DArea da = new DArea();
            var allProvinces = da.ChinaAreas.Where(ca => ca.ParentID == null);
            return Json(allProvinces.ToArray(), JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        public JsonResult GetNextLevel(string code)
        {
            try
            {
                if (code == null)
                {
                    return null;
                }
                DArea da = new DArea();
                int id = da.ChinaAreas.Where(ca => ca.Code == code).First().Id;
                var nextlevel = da.ChinaAreas.Where(ca => ca.ParentID == id);
                return Json(nextlevel.ToArray(), JsonRequestBehavior.AllowGet);
            }
            catch (Exception)
            {
                return null;
            }
        }
    }

 好的,目前我们站在使用者的角度写出这些代码。

接下来我们要实现@Html.AreaRender这个扩展方法。

向图1中的Hhelpers文件中添加一个静态类AreaRenderHelper

public static class AreaRenderHelper
    {
        /// <summary>
        /// 动态级联加载区划(省,市,县,乡,村)
        /// </summary>
        /// <param name="htmlhelper">扩展方法的指定参数</param>
        /// <param name="nameAndvalue">提供字段名称和取值的字典</param>
        /// <param name="getProvinceUrl">获取省份数据的路径名称</param>
        /// <param name="getNextLevelUrl">获取下一级数据的路径名称</param>
        /// <returns></returns>
        public static MvcHtmlString AreaRender(
            this HtmlHelper htmlhelper,
            Dictionary<string, string> nameAndvalue,
            string getProvinceUrl,
            string getNextLevelUrl)
        {
            MvcHtmlString mhs = htmlhelper.Partial("~/Views/AreaManager/AreaRender.cshtml",
                new { data = nameAndvalue, provinceUrl = getProvinceUrl, nextUrl = getNextLevelUrl }.ToExpando());
            return mhs;
        }
    }

在静态类AreaRenderHelper中我们看到.ToExpando() 方法,这个方法是要手动添加的,他是第三方提供的命名空间是System的扩展方法。

using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace System
{
    public static class ExpandoHelper
    {
        public static ExpandoObject ToExpando(this object anonymousObject)
        {
            IDictionary<string, object> anonymousDictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(anonymousObject);
            IDictionary<string, object> expando = new ExpandoObject();
            foreach (var item in anonymousDictionary)
                expando.Add(item);
            return (ExpandoObject)expando;
        }

    }
}
把该类也加在Helpers文件夹中吧。这个无所谓因为他的命名空间是:System

好的,该下班了,明天接着写控件所需的js。谢谢!


posted @ 2012-11-29 18:11  xiaobudian8493  阅读(2083)  评论(3编辑  收藏  举报