我在这里使用MVC 4,我有一个从XML文件生成的活动列表页面。可以检查多于1个活动,并且在每个活动中,用户可以设置日期,成人/儿童的数量。我的计划是当用户点击提交时,所有检查的活动都被放入ActivityItems列表中。以下是我将ActivityItem定义为:
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; }
}
My View看起来像这样(我拿出了很多样式和格式来使代码更容易阅读)。请注意,@ 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,并从列表中的活动填充以下字段:
但是可以单击多个项目,并且在提交表单时,我需要返回一个ActivityItems列表。我有一种感觉,这是一个复杂的答案,因此,我不期望一个完整的解决方案(虽然那将是非常棒的哈哈)。但是,如果我能得到一些提示和指示,那将是一个很大的帮助。我非常感谢所有的建议。
答案 0 :(得分:2)
当你想要为一个集合建模时,第一件事是生成的输入元素名称应该遵循一个模式。
实施例
@for (int i = 0; i < 3; i++)
{
@Html.TextBoxFor(m => m[i].Title)
@Html.TextBoxFor(m => m[i].Author)
}
请注意,您应将foreach
替换为for
,这将生成如下的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
}