【问题标题】:Model and ItemModel bindings in ASP.NET MVC4 ViewsASP.NET MVC4 视图中的模型和 ItemModel 绑定
【发布时间】:2013-06-26 16:06:17
【问题描述】:

我使用脚手架选项创建了一个SubscriptionController
下面是一些sn-ps的代码:

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; }

这是我的问题:

  1. 我认为Model 绑定到一个SubscriptionLIST,而不是一个Subscription 身份,因为这表明:

    @foreach(模型中的变量项)

    这是正确的吗?

  2. 如果1是正确的,为什么在这一行:

    @Html.DisplayNameFor(model =&gt; model.Amount)

    模型会有Amount?这表明模型绑定到单个“订阅”。

  3. 对于这一行:

    @Html.DisplayFor(modelItem =&gt; item.Amount) modelItem 和 item 绑定到什么?为什么 lambda 接受 modelItem 但不使用它?

请解释 Model、model 和 modelitem 到底绑定到什么。
谢谢。

【问题讨论】:

    标签: asp.net-mvc razor view model


    【解决方案1】:
    1. 没错。
    2. 它正在使用this 重载DisplayNameFor。这允许您从 IEnumerable 模型中获取单个项目以显示列标题等内容。
    3. modelItem 是你的模特。 item 来自 foreach。这有点作弊,允许您使用 DisplayFor 助手。

    关于第 3 项的更多信息。这对DisplayFor 很好。但是,如果您想制作可编辑的网格和EditorFor/TextboxFor,这将导致问题。 Razor 将根据传入的表达式为生成的 HTML 分配名称。因此,表中的所有项目都将具有相同的名称。但是,要发布集合,名称必须包含索引,例如 Item[0].AmountItem[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

    【讨论】:

    • 感谢您的详细解释..我按照您的建议创建了一个模板,现在它正在工作。只有一件事:您的链接已损坏,您只复制到 ....as 而不是 ...aspx
    • @octref 很好。请记住,您可以对问题和答案提出修改建议,如果您建议的修改获得批准,您将获得代表。
    • @cadrell0 当然,谢谢。我试图编辑它,但由于添加的“px”少于 6 个字符,我无法做到。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多