我使用脚手架选项来创建SubscriptionController
以下是一些代码段:
In Controller:
public ActionResult Index()
{
var subscriptions = db.Subscriptions;
return View(subscriptions.ToList());
}
In View:
@model IEnumerable<Liquidity.Domain.Entity.Subscription>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
@Html.DisplayNameFor(model => model.Amount)
</th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Amount)
</td>
</td>
</tr>
}
</table>
For my subscription model, I have:
public decimal Amount { get; set; }
以下是我的问题:
我认为Model
绑定到Subscription
的列表而不是Subscription
个身份,因为这是真的:
@foreach(模型中的var项目)
这是对的吗?
如果1是正确的,为什么在这一行:
@Html.DisplayNameFor(model => model.Amount)
模型会有Amount
?这表明模型绑定到单个“订阅”。
对于这一行:
@Html.DisplayFor(modelItem => item.Amount)
什么是modelItem和item绑定到?为什么lambda接受modelItem但不使用它?
请解释一下模型,型号和型号的确切含义。
感谢。
答案 0 :(得分:2)
DisplayNameFor
的{{3}}重载。这允许您从IEnumerable模型中获取单个项目以显示列标题等内容。modelItem
是您的模特。 item
来自foreach。这有点像作弊,允许你使用DisplayFor
助手。有关第3项的更多信息。这适用于DisplayFor
。但是,如果您想制作可编辑的网格EditorFor
/ TextboxFor
,则会出现问题。 Razor将根据传入的表达式将名称分配给生成的HTML。因此,表中的所有项都将具有相同的名称。但是,要发布集合,名称必须包含索引,例如Item[0].Amount
,Item[1].Amount
....
有两种方法可以完成这项工作。
首先,使用for
代替foreach
。您需要将模型更改为支持索引器,IList,ICollection等的内容。这看起来像。
@for(int i = 0; i < Model.Count; i++)
{
<tr>
<td>
@Html.EditorFor(model=> model[i].Amount)
</td>
</td>
</tr>
}
或者,我更喜欢,创建一个编辑器模板。在视图名称“EditorTemplates”中创建一个新文件夹。然后创建一个名为“Subscription.cshtml”的文件。此文件应如下所示
@model Subscription
<tr>
<td>
@Html.EditorFor(model=> model.Amount)
</td>
</td>
</tr>
现在在您看来,您可以
@Html.EditorFor(model => modle)
或
@Html.EditorForModel()
剃刀引擎非常聪明,可以重新定义您的模型是一个集合,它将为集合中的每个项目呈现EditorTemplate。此外,它将正确生成名称,因此您不必担心。使用此方法,您也可以继续使用IEnumerable
模型。
这也适用于DisplayTemplates。您只需将文件夹的名称更改为DisplayTemplates,然后使用DisplayFor
代替EditorFor
。