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


    今天很激动啊,昨天下午赶时间写的省市县乡村 动态级联加载控件AreaRender(一)已经有博友评论了,

    对于刚开始写博客的我是莫大的鼓励,我会继续写下去,逐步提高自己的文学素养,写出像 T2噬菌体博主一样受到大家欢迎的作品。

    好了,言归真转,接下来我们先分析一下关于分布视图~/Views/AreaManager/AreaRender.cshtml的编写问题。

    该分布视图包含两个部分:隐藏域(即用户要搜集的数据部分)和五个select下拉列表

    @*
      //功能:实现对省市县乡村的自动级联加载
      //作者:刘帅 liushuai@upway.cn
      //时间:2012.11.29 周四
      //使用说明:首先,用户需要提供一个字典,其中键对应字段名称,值就是对应字段的值;
      //         其次,要提供获取省份数据的url和获取下一级区划的url。
      //版本:v1.0
    *@
    @if (Model.data != null)
    {
        //原始数据
        Dictionary<string, string> ds = Model.data;
        //随即生成工作区,以免相互干扰
        Random random = new Random();
        System.Text.StringBuilder sb = new System.Text.StringBuilder();
        sb.Append((char)random.Next(65, 90));
        sb.Append((char)random.Next(97, 122));
        sb.Append((char)random.Next(97, 122));
        sb.Append((char)random.Next(97, 122));
        //定义工作区
        <div id="@sb.ToString()-div">
            @{
        //生成隐藏域,一次按照省市县乡村的顺序进行加载,便于操作 
        for (int i = 0; i < ds.Count; i++)
        {
                <input type="hidden" id="@ds.ElementAt(i).Key.Replace('.', '-')" name="@ds.ElementAt(i).Key" value="@ds.ElementAt(i).Value" />
        }
        //生成级联加载的结束标记
                <input type="hidden" id="end" value="@ds.ElementAt(5).Key.Replace('.', '-')" />
        //生成五个select:id,name和class的前缀均为'Spring-'以免发生冲突,也是我最喜欢的单词和季节;
        //onchange事件:1.刷新隐藏域的值,2.加载下一级;
        //第一个参数是工作区,第二个参数当前select的Id,第三个参数是下一个select的id,第四个参数是获取下一级区划的url,第五个参数是select的类
                <select id="Spring-province" name="Spring-province" class="Spring-select" onchange="AddNextLevel('#' + '@sb.ToString()-div #','Spring-province','Spring-city','@Model.nextUrl',' .Spring-select')">
                </select>
                <select id="Spring-city" name="Spring-city" class="Spring-select" onchange="AddNextLevel('#' + '@sb.ToString()-div #','Spring-city','Spring-country','@Model.nextUrl',' .Spring-select')">
                </select>
                <select id="Spring-country" name="Spring-country" class="Spring-select" onchange="AddNextLevel('#' + '@sb.ToString()-div #','Spring-country','Spring-town','@Model.nextUrl',' .Spring-select')">
                </select>
                <select id="Spring-town" name="Spring-town" class="Spring-select" onchange="AddNextLevel('#' + '@sb.ToString()-div #','Spring-town','Spring-village','@Model.nextUrl',' .Spring-select')">
                </select>
                <select id="Spring-village" name="Spring-village" class="Spring-select" onchange="AddNextLevel('#' + '@sb.ToString()-div #','Spring-village','','',' .Spring-select')">
                </select>
                <script type="text/javascript">
                    //触发加载省份信息
                    AddProvince("#" + "@sb.ToString()-div #", "Spring-province", "Spring-city", "@ds.ElementAt(0).Key.Replace('.', '-')", "@ds.ElementAt(1).Key.Replace('.', '-')", '@Model.provinceUrl', '@Model.nextUrl');
                </script>
            }
        </div>
    }

    出于对通用性的要求,我将该控件包含在一个动态生成id的div中,以避免不必要的冲突;

    这样一来,该控件就可以在同一个页面中存在多个,而又不产生混淆。当然这段代码也不是一蹴而就的,是在不断地思考,不断地修改。

    并且尽量减少该分部视图对外部的耦合度。

    我又详细的注释,大家又不理解的地方可以提出来,共同讨论。

    到目前为止,还有最终要的js文件没有编写,接下来让我们开始吧:

    首先,为便于理解,我将每一个方法都独立为一个Js文件。

    为了将该问题简化,我将该控件的加载过程很自然的分为两个阶段(大家很自然就能想到):

    1.为下拉选项卡赋值阶段

    2.动态级联加载阶段,也就是select的onchange事件

    其中第一阶段包含三个函数:AddProvince、SetValue和InitNextLevel

    //功能:初始化省份,调用SetValue为select赋值
    //作者:刘帅 liushuai@upway.cn
    //时间:2012.11.29 周四
    //参数说明:c->工作区div; province->省份对应的select的id; city->市对应的select的id
    //          f->当前隐藏域的id; s->下一个隐藏域的id; provinceUrl->获取省份信息的路径
    //          nextUrl->获取下一级数据的路径
    //版本:v1.0
    function AddProvince(c, province, city, f, s, provinceUrl, nextUrl) {
        //当前省份对应的select
        var sprovince = $(c + province);
        //异步加载所有省份,加载之后根据隐藏域的值为select赋值
        $.ajax(
            {
                type: "post",
                url: provinceUrl,
                datatype: "Json",
                success: function (data) {
                    if (data != null) {
                        //清空残留
                        sprovince.empty();
                        //追加新的options
                        var option = $("<option>").text(" ").val("");
                        sprovince.append(option);
                        $.each(data, function (i, item) {
                            var option = $("<option>").text(item.Name).val(item.Code)
                            sprovince.append(option);
                        });
                        SetValue(c, province, city, f, s, nextUrl);
                    }
                }
            });
    }
    //功能:初始化数据时,为select赋值,并调用InitNextLevel加载下一级
    //      当没有初始值时返回,当遇到结束标志是返回
    //作者:刘帅 liushuai@upway.cn
    //时间:2012.11.29 周四
    //参数说明:c->工作区div; fs->当前select的id; ss->下一个select的id
    //          f->当前隐藏域的id; s->下一个隐藏域的id; url->获取下一级数据的路径
    //版本:v1.0
    function SetValue(c, fs, ss, f, s, url) {
        //隐藏域的值
        var hiddenValue = $(c + f).val();
        if (hiddenValue == 0 || hiddenValue == null || hiddenValue == 'undefined') {
            //alert("没有值!!"); 没有初始值,返回
            return;
        }
        //为select赋值
        $(c + fs).val(hiddenValue);
        //如果遇到结束标志,返回
        if (f == $(c + "end").val()) {
            return;
        }
        //初始化下一级
        InitNextLevel(c, fs, ss, f, s, url);
    }
    //功能:初始化省以外的select,并调用SetValue为select赋值
    //作者:刘帅 liushuai@upway.cn
    //时间:2012.11.29 周四
    //参数说明:c->工作区div; fs->当前select的id; ss->下一个select的id
    //         f->当前隐藏域的id; s->下一个隐藏域的id; url->获取下一级数据的路径
    //版本:v1.0
    function InitNextLevel(c, fs, ss, f, s, url) {
        //隐藏域的值,根据上一个select的值获取下级数据
        var hiddenValue = $(c + f).val();
        var nextSelect = $(c + ss);
        $.ajax({
            type: "post",
            data: { "code": hiddenValue },
            url: url,
            datatype: "Json",
            success: function (data) {
                if (data != null) {
                    nextSelect.empty();
                    var option = $("<option>").text(" ").val("");
                    nextSelect.append(option);
                    $.each(data, function (i, item) {
                        var option = $("<option>").text(item.Name).val(item.Code)
                        nextSelect.append(option);
                    });
                    //移动到下一级别
                    fs = ss;
                    ss = $(c + fs).next("select").attr("id");
                    f = s;
                    s = $(c + f).next("input").attr("id");
                    SetValue(c, fs, ss, f, s, url);
                }
            }
        });
    }

    第二个阶段包含一个方法:AddNextLevel

    //功能:select的onchange事件,保存已选值,加载下一级数据
    //作者:刘帅 liushuai@upway.cn
    //时间:2012.11.29 周四
    //参数说明:c->工作区div; fs->当前select的id; ss->下一个select的id selectClass->select的class
    //版本:v1.0
    function AddNextLevel(c, fs, ss, url, selectClass) {
        //清除当前节点之后所有select的值
        $(c + fs).nextAll("select").each(function (i, item) {
            $(item).empty();
        });
        var selects = $(c.substr(0, c.length - 2) + selectClass);
        var ids = $(c.substr(0, c.length - 2) + " input");
        //遍历c区域中所有的select值,并赋值给隐藏域(包含两部分:id和name,需要重载)
        for (var i = 0; i < 5; i++) {
            ids[i].value = selects[i].value;
            var selectValue = $(c + selects[i].id + " option:selected").text();
            ids[i + 5].value = selectValue;
        }
        var nextSelect = $(c + ss);
        //异步加载下一级别
        $.ajax({
            type: "post",
            data: { "code": $(c + fs + " option:selected").val() },
            url: url,
            datatype: "Json",
            success: function (data) {
                if (data != null) {
                    nextSelect.empty();
                    var option = $("<option>").text(" ").val("");
                    nextSelect.append(option);
                    $.each(data, function (i, item) {
                        var option = $("<option>").text(item.Name).val(item.Code)
                        nextSelect.append(option);
                    });
                }
            }
        });
    }

    F5调试:

    更改第一个省份之后:

    修改第二个的所有值:

    生成的html代码:

    <!DOCTYPE html>
    <html>
    <head>
        <title>测试地区的级联加载</title>
        <link href="/Content/Site.css" rel="stylesheet" type="text/css" />
        <script src="/Scripts/jquery-1.5.1.min.js" type="text/javascript"></script>
    </head>
    
    <body>
            <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>
    <form action="/Home/Save" method="post">
        <div id="Sjih-div">
                <input type="hidden" id="pro-id" name="pro.id" value="650000000000" />
                <input type="hidden" id="cit-id" name="cit.id" value="650100000000" />
                <input type="hidden" id="cou-id" name="cou.id" value="650102000000" />
                <input type="hidden" id="tow-id" name="tow.id" value="650102002000" />
                <input type="hidden" id="vil-id" name="vil.id" value="650102002002" />
                <input type="hidden" id="pro-name" name="pro.name" value="新疆维吾尔自治区" />
                <input type="hidden" id="cit-name" name="cit.name" value="乌鲁木齐市" />
                <input type="hidden" id="cou-name" name="cou.name" value="天山区" />
                <input type="hidden" id="tow-name" name="tow.name" value="燕儿窝街道" />
                <input type="hidden" id="vil-name" name="vil.name" value="燕儿窝南社区居委会" />
                <input type="hidden" id="end" value="pro-name" />
                <select id="Spring-province" name="Spring-province" class="Spring-select" onchange="AddNextLevel('#' + 'Sjih-div #','Spring-province','Spring-city','/Home/GetNextLevel',' .Spring-select')">
                </select>
                <select id="Spring-city" name="Spring-city" class="Spring-select" onchange="AddNextLevel('#' + 'Sjih-div #','Spring-city','Spring-country','/Home/GetNextLevel',' .Spring-select')">
                </select>
                <select id="Spring-country" name="Spring-country" class="Spring-select" onchange="AddNextLevel('#' + 'Sjih-div #','Spring-country','Spring-town','/Home/GetNextLevel',' .Spring-select')">
                </select>
                <select id="Spring-town" name="Spring-town" class="Spring-select" onchange="AddNextLevel('#' + 'Sjih-div #','Spring-town','Spring-village','/Home/GetNextLevel',' .Spring-select')">
                </select>
                <select id="Spring-village" name="Spring-village" class="Spring-select" onchange="AddNextLevel('#' + 'Sjih-div #','Spring-village','','',' .Spring-select')">
                </select>
                <script type="text/javascript">
                    //触发加载省份信息
                    AddProvince("#" + "Sjih-div #", "Spring-province", "Spring-city", "pro-id", "cit-id", '/Home/GetProvinces', '/Home/GetNextLevel');
                </script>
        </div>
    
        <div id="Rwpe-div">
                <input type="hidden" id="pro-id" name="pro.id" value="650000000000" />
                <input type="hidden" id="cit-id" name="cit.id" value="650100000000" />
                <input type="hidden" id="cou-id" name="cou.id" value="650102000000" />
                <input type="hidden" id="tow-id" name="tow.id" value="650102002000" />
                <input type="hidden" id="vil-id" name="vil.id" value="650102002002" />
                <input type="hidden" id="pro-name" name="pro.name" value="新疆维吾尔自治区" />
                <input type="hidden" id="cit-name" name="cit.name" value="乌鲁木齐市" />
                <input type="hidden" id="cou-name" name="cou.name" value="天山区" />
                <input type="hidden" id="tow-name" name="tow.name" value="燕儿窝街道" />
                <input type="hidden" id="vil-name" name="vil.name" value="燕儿窝南社区居委会" />
                <input type="hidden" id="end" value="pro-name" />
                <select id="Spring-province" name="Spring-province" class="Spring-select" onchange="AddNextLevel('#' + 'Rwpe-div #','Spring-province','Spring-city','/Home/GetNextLevel',' .Spring-select')">
                </select>
                <select id="Spring-city" name="Spring-city" class="Spring-select" onchange="AddNextLevel('#' + 'Rwpe-div #','Spring-city','Spring-country','/Home/GetNextLevel',' .Spring-select')">
                </select>
                <select id="Spring-country" name="Spring-country" class="Spring-select" onchange="AddNextLevel('#' + 'Rwpe-div #','Spring-country','Spring-town','/Home/GetNextLevel',' .Spring-select')">
                </select>
                <select id="Spring-town" name="Spring-town" class="Spring-select" onchange="AddNextLevel('#' + 'Rwpe-div #','Spring-town','Spring-village','/Home/GetNextLevel',' .Spring-select')">
                </select>
                <select id="Spring-village" name="Spring-village" class="Spring-select" onchange="AddNextLevel('#' + 'Rwpe-div #','Spring-village','','',' .Spring-select')">
                </select>
                <script type="text/javascript">
                    //触发加载省份信息
                    AddProvince("#" + "Rwpe-div #", "Spring-province", "Spring-city", "pro-id", "cit-id", '/Home/GetProvinces', '/Home/GetNextLevel');
                </script>
        </div>
    </form>
    </body>
    </html>

    到这里,我已经把所有的文件都分享出来了,希望大家提出其中的bug和修改办法,共同学习进步!

    期待大家的评论,顺便可以加关注!呵呵呵

  • 相关阅读:
    DELPHI SOKET 编程(使用TServerSocket和TClientSocket)
    DELPHI 任务栏无EXE显示
    Delphi 实现无窗口移动(详细使用WM_NCHITTEST和PtInRect API进行测试)
    ViewPager的简单使用
    delphi 网页提交按钮执行点击事件
    Delphi 获取网站验证码的图片
    Delphi 模拟网站验证码(酷,把随机文字写道图片上)
    张文木的文章都很不错,有空仔细看看
    深度RAMOS,把操作系统全部安装在内存上
    C# ASP.net 入门之简单通讯录
  • 原文地址:https://www.cnblogs.com/LiuShuaiXiaoBuDian/p/AreaRenderHelper2.html
Copyright © 2020-2023  润新知