我正在使用asp.net mvc 3并且想到处理这种情况的最佳方法是。
假设我有一个创建奖励结构的表单。在这种情况下,他们可以获得多种奖励水平
例如
$100 to $500 - get .05% back
$501 to $1000 - get 0.6% back
$1001 to $1001 - get 0.7% back
and so forth.
现在这些层以我正在创建的形式输入。可能有一个奖励等级或可能有5层或50层。我只是不知道。
选项1
对5层进行人为限制。如果他们只需要一层井,他们仍然必须通过向导形式(通过jquery)我正在创建并跳过接下来的4层屏幕(他们将需要填写相当多的字段,所以我决定做它一个巫师,所以它不会立刻压倒一切。)
public class MasterVm
{
public IList<TiersVm> Tiers { get; set; }
public MasterVm()
{
Tiers = new List<TiersVm>();
}
}
@for (int i = 0; i < Model.Tiers.Count; i++)
{
@Html.LabelFor(x => x.Tiers[i].StartOfRange, "Start Of Range")
@Html.TextBoxFor(x => x.Tiers[i].StartOfRange)
@Html.LabelFor(x => x.Tiers[i].EndOfRange, "End Of Range")
@Html.TextBoxFor(x => x.Tiers[i].EndOfRange)
// more fields here
}
在我的控制器中,我会制作5个占位符,因此for循环将会循环5次。
选项2
使表单生成另一个层级按钮。他们点击它,将制作另一层。这样,如果他们只有一个,他们只看到一次,如果他们有100则无关紧要。
我正在考虑使用jquery clone来实现这一点,但我不知道视图模型绑定是如何工作的。看看id了吗?还是名字?
当我做选项时,我的所有控件都看起来像这样
<input id="Tiers_0__StartOfRange" type="text" value="0" name="Tiers[0].StartOfRange">
他们都有独特的id(好的)和独特的名字。我不确定在克隆代码中我是否应该删除id和名称。或者我是否需要在其中生成代码以生成如上所示的id和名称?
我将使用jquery.serializeArray()通过ajax提交所有内容,并且在控制器中我将有一个参数,View Model也应该绑定。
答案 0 :(得分:1)
我不喜欢MVC3使用的开箱即用的索引模式。在我们的应用程序中,我们使用Steve Sanderson's BeginCollectionItem HTML helper。它会覆盖默认行为,并使用GUID而不是整数来索引多个项目。
我建议你做选项#2,但是在服务器上做克隆/收集项目工厂的东西,然后使用ajax将HTML返回到视图。 Steve的助手使用默认的模型绑定器,因此当您发布表单时,最终会得到一个从表单输入绑定的层模型集合。
单层的局部视图示例:
@model TiersVm
<div class="tier-item">
@using(Html.BeginCollectionItem("Tiers"))
{
Html.LabelFor(x => x.StartOfRange, "Start Of Range")
Html.TextBoxFor(x => x.StartOfRange)
Html.LabelFor(x => x.EndOfRange, "End Of Range")
Html.TextBoxFor(x => x.EndOfRange)
// more fields here
}
</div>
当用户点击“添加图层”按钮时,您将拥有一个返回上述部分的操作方法。
public PartialViewResult GenerateTier()
{
return PartialView(new TiersVm());
}
BeginCollectionItem帮助器将呈现所有输入名称和id,以便它们可以反弹到您正在POST的模型中:
@model MasterVm
... using BeginForm ....
<div class="tier-container"> @* clicking new tier button appends items here *@
@foreach (var tier in Model.Tiers)
{
Html.Action("GenerateTier", "ControllerName")
}
</div>
然后使用默认模型绑定器
进行魔术[HttpPost]
public ActionResult ReceiveInput(MasterVm masterVm)
{
// masterVm.Tiers has been populated by the default model binder
}
答案 1 :(得分:0)
指南是元素的ID必须与ViewModel属性名称相对应 其余的都是你的决定。
如果您创建对服务器的AJAX调用,则必须使URL参数与模型属性
相对应您可以编写一个自定义模型绑定器,根据您所需的逻辑进行绑定。自定义IModelBinder的一个示例,您可以找到here
请注意MVC团队的建议:
一般情况下,我们建议人们不要编写自定义模型绑定器 因为他们很难做对,很少需要他们