如何在分组列表中发布带有已编辑项目的模型?

时间:2014-09-25 07:41:51

标签: asp.net-mvc razor model

我有以下问题。我需要在分组列表中编辑项目值并将模型发布到服务器。

我的模型和视图模型:

public class MyObject
{
    public string ParentName { get; set; }
    public string SubParentName { get; set; }
    public string ItemName { get; set; }
    public decimal Value { get; set; }
}

public class MyViewModel
{
    public IList<MyObject> list;
}

简化(没有分组项的html表分组)视图的实现:

@model MyViewModel

@(using (Html.BeginForm("Action", "Controller", FormMethod.Post)))
{
    <table>
        <tbody>
            @foreach(var parentItems in Model.list.GroupBy(x => x.ParentName))
            {
                foreach(var subParents in parentItem.GroupBy(x => x.SubItemName))
                {
                    foreach (var item in subParents)
                    {
                        <tr>
                            <td><parentItems.FirstOrDefault().ParentName</td>
                            <td><subParents.FirstOrDefault().SubParentName</td>
                            <td>item.ItemName</td>
                            <td><input class="itemValue">**Editable value item.Value**</td>
                        </tr>
                    }
                }
            }
        </tbody>
    </table>

    <button type="submit">Save</button>
}

怎么做?

解决

@model MyViewModel

@(using (Html.BeginForm("Action", "Controller", FormMethod.Post)))
{
    <table>
        <tbody>
            @foreach(var parentItems in Model.list.GroupBy(x => x.ParentName))
            {
                @{ var counter = 0;}  
                foreach(var subParents in parentItem.GroupBy(x => x.SubItemName).Select(x => x.ToList()))
                {
                    for(int i = 0; i < subParents.Count(); i++, counter++)
                    {
                        <tr>
                            <td>
                                @Html.DisplayFor(x => x.list[counter].ItemName)
                                @Html.HiddenFor(x => x.list[counter].ItemName)

                            </td>
                            <td>
                                @Html.TextBoxFor(x => x.list[counter].Value, new { myAttr = "myAttrValue"});
                            </td>                           
                        </tr>

                        @Html.HiddenFor(x => x.Reports[counter].ParentName)
                        @Html.HiddenFor(x => x.Reports[counter].SubParentName)
                    }
                }
            }
        </tbody>
    </table>

    <button type="submit">Save</button>
}

谢谢大家的帮助:)

2 个答案:

答案 0 :(得分:1)

您的控制器代码:

[HttpPost]
public ActionResult Action([FromBody] values)
{
}

您的观看代码:

@(using (Html.BeginForm("Action", "Controller", FormMethod.Post)))
{
    <table>
        <tbody>
            @for(int i =0; i< Model.Count; i++)
            {
                 <tr>
                     <td>
                          @Html.DisplayFor(x=> x.ParentName)
                          @Html.HiddenFor(x=> x.ParentName)
                     </td>
                     <!-- same to all not editable fields -->
                     <td>@Html.TextBoxFor(x=> x.Value)</td>
                 </tr>
            }
        </tbody>
    </table>

    <button type="submit">Save</button>
}

答案 1 :(得分:1)

有趣的问题。使用foreach循环不起作用,因为控件将没有正确的索引name属性用于回发,并且单个for循环不允许进行分组,除非您包含条件检查(例如,如果ParentNameSubParentName已从先前呈现的项目发生更改,然后呈现新的组标题或启动新表格等等。

我建议您创建一个视图模型,以更好地表示层次结构并在控制器上填充视图模型

public class MyObject
{
  public string ParentName { get; set; }
  public string SubParentName { get; set; }
  public string ItemName { get; set; }
  public decimal Value { get; set; }
}

public class SubParentVM
{
  public string Name { get; set; } // assuming you want some kind of group heading
  public List<MyObject> Items { get; set; }
}

public class ParentVM
{
  public string Name { get; set; }
  public List<SubParentVM> Items { get; set; }
}

和视图

@model List<ParentVM>

for (int i = 0; i < Model.Count; i++)
{
  ....
  for (int j = 0; j < Model[i].Items.Count; i++)
  {
    ....
    for (int k = 0; k < Model[i].Items[j].Count; i++)
    {
      <tr>
        <td>Model[i].Items[j].Items[k].ParentName</td>
        <td>Model[i].Items[j].Items[k].SubParentName</td>
        <td>Model[i].Items[j].Items[k].ItemName</td>
        <td>
          <@Html.TextBoxFor(m => m.[i].Items[j].Items[k].Value)
          // Assuming you want other properties of MyObject to post back
          <@Html.HiddenFor(m => m.[i].Items[j].Items[k].ItemName)
          <@Html.HiddenFor(m => m.[i].Items[j].Items[k].SubParentName)
          <@Html.HiddenFor(m => m.[i].Items[j].Items[k].ParentName)
        </td>
      </tr>
    }
  }
}

控制器

[HttpPost]
public ActionResult Save(List<ParentVM> items)
{
  ....