zoukankan      html  css  js  c++  java
  • Asp.Net MVC2 控件开发实例(1)

    项目中“详细地址”这一数据项要细化到门牌号,比如北京市—海淀区—北四环西路—叉叉楼—5单元—1号,页面上表现为一个数据项,但实际上这个数据项包含很多子项,且不能随意编辑,比如说你自己写了个“宇宙1号楼”,这是不合规范的,那么我就要做一个控件,实现这样一个功能:点击一个标题为"详细地址"的文本框,会弹出一个层,里面有各个地址子项的选择,选择后点确定,会关闭这个弹出层并把选择的结果显示在最开始点击的文本框,最好里面存的是可序列化的数据。我要的效果如下图:

     

    在提交页面时我需要获取到详细地址的所有子项,当然通过formcollection应该可以一项一项获取到,不过就需要每个用到这个控件的人自己来控制,比较麻烦。在这里我将所有的子项名称和值组合成一个json串保存在一个隐藏控件中。构建htmlhelper不多说了,直接上代码:

    helper
     1 public static MvcHtmlString AddressFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expressionMC, Expression<Func<TModel, TValue>> expressionDM, object htmlAttributes)
     2         {
     3             string modelMCName = ExpressionHelper.GetExpressionText(expressionMC);
     4             string modelDMName = ExpressionHelper.GetExpressionText(expressionDM);
     5 
     6             StringBuilder sb = new StringBuilder();
     7             TagBuilder tag = new TagBuilder("input");
     8             tag.Attributes.Add("type""text");
     9             tag.Attributes.Add("name", modelMCName);
    10             tag.GenerateId(modelMCName);
    11 
    12             TagBuilder tagHidden = new TagBuilder("input");
    13             tagHidden.Attributes.Add("type""hidden");
    14             tagHidden.Attributes.Add("name", modelDMName);
    15             tagHidden.GenerateId(modelDMName);
    16 
    17             StringBuilder sbClick = new StringBuilder();
    18             sbClick.Append("if($('#divHid').html().length < 1){");
    19             sbClick.Append("$.post('/FM/Address/AddressFloatView',function(data){$('#divHid').html(data);}");
    20             sbClick.Append(")};");
    21             sbClick.Append("$('#divHid').dialog('open');");
    22 
    23             RouteValueDictionary dictionary = new RouteValueDictionary();
    24             dictionary.Add("onclick", sbClick.ToString());
    25             if (htmlAttributes != null)
    26                 tag.MergeAttributes(new RouteValueDictionary(htmlAttributes));
    27             tag.MergeAttributes(dictionary);
    28             sb.Append(tag.ToString(TagRenderMode.SelfClosing));
    29             sb.Append(tagHidden.ToString(TagRenderMode.SelfClosing));
    30             sb.Append(GetScript(modelMCName, modelDMName));
    31             return MvcHtmlString.Create(sb.ToString());
    32         }

     这里我绑定了两个lamda表达式,一个是可见文本框的,一个是隐藏域的,这样方便后面取值。 

    GetScript方法
     1 private static string GetScript(string modelMCName, string modelDMName)
     2         {
     3             StringBuilder script = new StringBuilder();
     4             script.Append("<script type='text/javascript'>");
     5             script.Append("$(function () {");
     6             script.Append("$(document.forms[0]).after('<form id=\"formAddress\"><div id=\"divHid\"></div></form>');");
     7             script.Append("initDialog('#formAddress', '标准化地址', '#divHid', 400, 530);");
     8             script.Append("});");
     9             script.Append("function setValToAddress(){");
    10             script.Append("var v='';var jsonContent = '{';");
    11             script.Append("$.each($('#divHid input[type!=\"button\"]'),");
    12             script.Append("function (i, n) {if ($(this).attr('type') == 'text' && $(this).attr('disabled') == false) v += $(this).val(); ");
    13             script.Append("jsonContent += '\"' + $(this).attr('id') + '\":\"' + $(this).val() + '\",';});");
    14             script.Append("jsonContent = jsonContent.substring(0, jsonContent.length - 1) + '}';");
    15             script.AppendFormat("$('{0}').val(v);""#" + modelMCName);
    16             script.AppendFormat("$('{0}').val(jsonContent);""#" + modelDMName);
    17             script.Append("}");
    18 
    19             script.Append("</script>");
    20             return script.ToString();
    21         }

    调用时为以下形式:

     地址标准化测试helper:<%=Html.AddressFor(m => m.Address, m => m.HidAddress, new { @style = "300px" })%>

     由于特殊原因,弹出层的代码我选择了异步加载:$.post('/FM/Address/AddressFloatView',function(data){$('#divHid').html(data);}

     AddressFloatView是这个PartialView的action,里面直接return PartialView(address);不过异步action要加[HttpPost()]。

     做到这,我已经可以获取到拼接后的详细地址的名称(保存在文本控件中)和详细地址的代码,值的json字符串,如下图

     

     隐藏域的html为

    代码
    1 <INPUT id=HidAddress value='{"DZ_XZQH":"110000","Auto_DZ_XZQH":"北京","DZ_PCS":"320502520000","Auto_DZ_PCS":"沧浪分局公园派出所","DZ_JLX":"","Auto_DZ_JLX":"","DZ_MPQZ":"01","Auto_DZ_MPQZ":"附","DZ_MPH":"32","DZ_MPHZ":"1","Auto_DZ_MPHZ":"号","DZ_FH":"456","DZ_FHHZ":"1","Auto_DZ_FHHZ":"号","DZ_ZLQZ":"01","Auto_DZ_ZLQZ":"东楼","DZ_ZLH":"567","DZ_ZLHZ":"2","Auto_DZ_ZLHZ":"栋","DZ_DYH":"23","DZ_SH":"43","DZ_SHHZ":"2","Auto_DZ_SHHZ":"号","DZ_FSDZ":"地球","DZ_DJDW":"320500000000","DZ_DJR":"320500000000201000000255","DZ_DJSJ":"2010-12-07"}' type=hidden name=HidAddress /> 

    现在我要反序列化这个json(在这之前自然要定义一个实体类StandardAddressModels ,与json的key一一对应)

    代码
    public static StandardAddressModels ConvertToAddressModel(string jsonString)
            {
                MemoryStream stream 
    = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
                DataContractJsonSerializer ser 
    = new DataContractJsonSerializer(typeof(StandardAddressModels));
                stream.Position 
    = 0;
                StandardAddressModels address 
    = (StandardAddressModels)ser.ReadObject(stream);
                stream.Close();
                
    return address;
            }

     现在我就可以调用这个方法获取序列化的结构体了:

    StandardAddressModels address = ForeignerManagement.CommonFunction.FMCommon.ConvertToAddressModel(jsonString); 

    扩展一下,反序列化为其他的结构体 :

    需要定义一个接口 IDataContract ,然后向反序列化的结构体继承这个接口即可

    代码:

    public static StandardAddressModels ConvertToAddressModel(string jsonString)
            {
                MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
                DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(StandardAddressModels));
                stream.Position = 0;
                StandardAddressModels address = (StandardAddressModels)ser.ReadObject(stream);
                stream.Close();
                return address;
            }

     调用时:
    1 StandardAddressModels address = new StandardAddressModels();
    2 address = ForeignerManagement.CommonFunction.FMCommon.ConvertToModel(jsonString, address.GetType());

    不写这句上面代码不出来,博客园bug。。

  • 相关阅读:
    sklearn中禁止输出ConvergenceWarning:
    sklearn里训练集和测试集的分割
    sklearn模型的保存与加载使用
    django项目成功启动,但views里代码未执行
    使用sklearn对iris数据集做基本的训练和预测
    unrecognized option '--high-entropy-va'
    快速下载Mingw(不使用sourceforge.net)
    cc1.exe: sorry, unimplemented: 64-bit mode not compiled in
    GoLand里Go Module模式下import自定义包
    GoLand生成可执行文件(Windows、Linux)
  • 原文地址:https://www.cnblogs.com/dzxw2371/p/1899182.html
Copyright © 2011-2022 走看看