MVC动态列表绑定

时间:2017-03-17 15:23:33

标签: asp.net-mvc list kendo-grid model-binding

我在模型中有一个List属性

public class MyModel
{
   public MyModel()
    {
        ChildModels = new List<ChildModels>();
    }
  // other properties
  public List<ChildModel> ChildModels {get; set;}
}

public class ChildModel
{
    public int Id {get;set;}
    public int Name {get;set;}
    public int Value {get;set;}
}

在表单提交中生成的html标记就像这样

<div class="form-group">
    <input data-val="true" data-val-number="The field Id must be a number." data-val-required="The Id field is required." id="ChildModels_0__Id" name="ChildModels[0].Id" type="hidden" value="0">
    <input id="ChildModels_0__Name" name="ChildModels[0].Name" type="hidden" value="value 1">
    <div class="control-label col-md-3">
        <label for="Value">value 1</label>
    </div>
    <div class="control-text col-md-7">
        <input class="form-control" id="ChildModels_0__Value" name="ChildModels[0].Value" type="text" value="">
    </div>
</div>

当回发表单时,ChildModels正在null。其他属性有值。我甚至无法在Google Chrome中的“网络”标签的“请求”标题中看到ChildModels

谢谢!

修改

这个问题是由于Kendo Grid造成的。在编辑器模板中编辑记录时,它不会解析子对象。 要解决这个问题,我必须编写一个解析子对象的javascript函数..像这样

&#13;
&#13;
function serialize(data) {
    serializeArray("ChildModels", data["ChildModels"], data);
}

function serializeArray(prefix, array, result) {
    var listattrs = $(".ValueAttributesClass"); // Add this class to one of the property of your child model 
    for (var i = 0; i < listattrs.length; i++) {
        result[prefix + "[" + i + "].Id"] = $("#" + listattrs[i].id).val();
        result[prefix + "[" + i + "].Name"] = $("#" + listattrs[i].id.replace("Id", "Name")).val();
        result[prefix + "[" + i + "].Value"] = $("#" + listattrs[i].id.replace("Id", "Value")).val();
    }
}

// In create event of kendo grid
.Create(update => update.Action("createactionmethod","controller").Data("serialize");
&#13;
&#13;
&#13;

希望它可以帮助有需要的人。

谢谢!

1 个答案:

答案 0 :(得分:0)

如果您必须将列表中的现有值填充到UI,并且该列表可能会由于用户交互而增长,那么将动态列表绑定到控制器的最简单方法是映射并创建JS数组,然后进行字符串化然后将其绑定到表单中的隐藏控件,然后提交将字符串化的JS数组绑定到相应操作方法的字符串参数的表单,然后将该字符串反序列化为该操作方法中的有效格式。 通过为HTML控件和getElementsByClassName提供通用的类名,可以完成映射和创建JS数组。

如果要从数据库中显示数据,请从db中获取数据,然后在ChildModels属性中填充该数据。

public class MyModel
{
   public MyModel()
   {
       ChildModels = new List<ChildModels>();
   }
   // other properties
   public List<ChildModel> ChildModels {get; set;}

   // if you want to use the same model to submit, bind to this property
   //public string StringifiedJSArray {get; set;}
}

public class ChildModel
{
   public int Id {get;set;}
   public int Name {get;set;}
   public int Value {get;set;}
}

in cshtml :

@model MyModel;
<button onclick="addChild()">Add Child</button>
<form id="myForm" asp-action="submit" asp-controller="..."> 
  <div id="myDiv">
    //only if you need to populate data in UI from backend
    @foreach(var child in Model.ChildModels)
    {        
      <input class="ChildName" value="child.Name">
      <input class="ChildValue" value="child.Value">        
    }
 <div>
 <input hidden name="StringifiedJSArray">
 <button type="button" onclick="submit()">Submit</button>
</form>

<script>
  function addChild(){
    $("myDiv").append('
      <input class="ChildName">
      <input class="ChildValue">
    ');
  }



function submit(){
   var Names = document.getElementsByClass('ChildName');
   var Values = document.getElementsByClass('ChildValue');
   var myArray = [];
   for(var i = 0; i < Names.length; i++)
   {
      var obj = {id:"Your custom logic",Name:Names[i].value,Values[i].value}
      myArray.push(obj);
   }
   document.getElementById('StringifiedJSArray').value = JSON.stringify(myArray);
   document.getElementById('myForm').submit();
  }
</script>

在控制器操作中:

public void submit(string StringifiedJSArray)
{
    public List<ChildModel> Children = JsonConvert.DeserializeObject<List<ChildModel>>(StringifiedJSArray)
    ...
    ... your logic
}