0

我在这里使用 MVC 4,并且我有一个从 XML 文件生成的活动列表的页面。可以检查超过 1 个活动,并且在每个活动中,用户可以设置日期、成人/儿童人数。我的计划是当用户点击提交时,所有被检查的活动都被放入一个 ActivityItems 列表中。这是我将 ActivityItem 定义为:

活动项目类

public class ActivityItem
{
    public string ActivityID { get; set; }
    public string Name { get; set; }
    public string Date { get; set; }
    public int NumAdults { get; set; }
    public int NumChildren { get; set; }
    public decimal TotalPrice { get; set; }
}

我的视图看起来像这样(我去掉了很多样式和格式以使代码更易于阅读)。请注意,@item.ActivityID 从“ACT001”开始,然后是“ACT002”,然后是“ACT003”,以此类推,直到 n 次。

@model IEnumerable<Project.Models.Activity>

@using (Html.BeginForm())
{
<ul data-role="listview" data-inset="true">
@foreach (var item in Model)
{
    <li>
        <div class="activity" id="@item.ActivityID">
            <h3>@item.Name</h3>
            <input type="checkbox" id="@item.ActivityID-Check" name="checkbox"/>  

        <label for="select-choice-0" class="select">Date:</label>
        <select name="select-choice-0" id="@item.ActivityID-Date">
            <option value="07/03/2012">07/03/2012</option>
            <option value="07/04/2012">07/04/2012</option>
            <option value="07/05/2012">07/05/2012</option>
            <option value="07/06/2012">07/06/2012</option>
        </select>   

        @Html.DropDownList(item.ActivityID+"-AdultNum", AdultNum)<br />
        Price/Adult C$:@Html.TextBox(item.ActivityID+"-AdultPrice", item.PricePerAdult)

        @Html.DropDownList(item.ActivityID+"-ChildNum", ChildNum)<br /> 
        Price/Child C$: @Html.TextBox(item.ActivityID+"-ChildPrice", item.PricePerChild)

        <label style="color:Blue"><h3>Total Price C$:</h3></label>
        <input type="text" id="@item.ActivityID-Sum" readonly="readonly"/>

        </div> 
    </li>
}
</ul>
<input type="submit" id="submit" value="Submit" />
}

因此,基本上,如果单击特定项目(@item.ActivityID-Check)的复选框并提交表单:

将使用从列表中的活动填充的以下字段创建一个 ActivityItem:

  • 项目清单
  • ActivityID = @item.ActivityID
  • 名称 = @item.Name
  • 日期 = @item.ActivityID-日期
  • NumAdults = @item.ActivityID-AdultNum
  • NumChildren = @item.ActivityID-ChildNum
  • TotalPrice = @item.ActivityID-Sum

但是可以单击多个项目,并且在提交表单时,我需要返回一个 ActivityItems 列表。我觉得这是一个复杂的答案,因此,我不希望有一个完整的解决方案(尽管那会很棒哈哈)。但是,如果我能得到一些提示和指示,那将是一个很大的帮助。我真的很感激所有的建议。

4

1 回答 1

2

当您想对集合进行模型绑定时,第一件事是输入元素的生成名称应遵循某种模式。

前任。

@for (int i = 0; i < 3; i++) 
{
  @Html.TextBoxFor(m => m[i].Title)
  @Html.TextBoxFor(m => m[i].Author)
}

请注意,您应该替换foreachfor,这将生成一个 html 表单,如下所示,

<form method="post" action="/Home/Create">    
    <input type="text" name="[0].Title" value="Curious George" />
    <input type="text" name="[0].Author" value="H.A. Rey" />

    <input type="text" name="[1].Title" value="Code Complete" />
    <input type="text" name="[1].Author" value="Steve McConnell" />

    ...
</form>

在您的情况下,接下来的事情是您必须仅将所选项目绑定到集合。所以你必须做几件事,1.删除未选中的 html 元素 2.重置输入元素的名称以及在表单提交事件中所做的这两件事。

$("form").submit(function() {

   // iterate the the activities and remove the ones that are not selected 
   // ex.
   $(this).children('[0].Title').remove();
   $(this).children('[0].Author').remove();

   // again iterate the activities in the form and reset their index values
   // ex.
   $(this).children('[1].Title').attr('name', [0].Title);
   $(this).children('[1].Author').attr('name', [0].Author);
});

更新:

另一种解决方案是您可以创建一个视图模型,该模型包含ActivityItem一个布尔标志,表示用户是否选择了特定活动。从发布操作中,您可以过滤用户选择的活动。视图模型在这种情况下很有帮助,这样你就可以避免监听表单提交事件。

public class ActivityItemViewModel
{
   public class ActivityItem { get; set; }
   public bool IsSelected { get; set; }
}

视图必须绑定到IEnumerable<Project.Models.ActivityItemViewModel>而不是IEnumerable<Project.Models.Activity>. 用于选择活动的复选框必须绑定到IsSelected属性。

@Html.CheckBoxFor(m => m[i].Isselected)

您将有一个控制器操作,将此集合作为输入,

public ActionResult PostAction(IEnumerable<Project.Models.ActivityItemViewModel>)
{
    .. now you can easily filter the Activities that are selected by checking the
    .. IsSelected boolean flag
}
于 2012-07-05T02:58:06.367 回答