【问题标题】:Create dynamic forms in ASP.NET MVC在 ASP.NET MVC 中创建动态表单
【发布时间】:2015-08-26 15:01:06
【问题描述】:

我有一个 ASP.NET MVC 应用程序,它通过采购订单跟踪我们公司的供应商。每个 PO 评级都分配了一个类型。每种类型可以有多个评级部分,每个评级部分可以有多个类别。这些类看起来像这样:

public class RatingModel{
    /*Fields for the purchase order*/

    public List<RatingSectionModel> RatingSections { get; set; }
}

public class RatingSectionModel {
    /*Fields for the Rating section*/

    public List<RatingCategoryModel > Categories { get; set; }
}

public class RatingCategoryModel {
    /*Fields for the category*/
}

在我的项目中,我尝试使用找到的修改后的 BeginCollectionItem here。 cshtml是:

_RatingModel.cshtml:

@model VendorRating.Models.RatingModel
@Html.HiddenFor(model => model.VendorId)
@Html.HiddenFor(model => model.VendorName)
@Html.HiddenFor(model => model.AwardDate)
@Html.HiddenFor(model => model.AwardValue)
@Html.HiddenFor(model => model.CloseDate)
@Html.HiddenFor(model => model.FinalValue)
@Html.HiddenFor(model => model.ServiceRep)
@Html.HiddenFor(model => model.PoId)

<div style="display:table;margin-bottom:5px;">
    <div style="display:table-row">
        <div style="display:table-cell;vertical-align:top;">
            @Html.LabelFor(model => model.TypeId)
        </div>
        <div style="display:table-cell;vertical-align:top;">
            @Html.DropDownListFor(model => model.TypeId, Model.Types)
        </div>
    </div>
</div>
<table>
    <tr>
        <td class="table-header">@Html.LabelFor(model => model.PoId, htmlAttributes: new { @class = "control-label" })</td>
        <td class="table-header">@Html.LabelFor(model => model.VendorName, htmlAttributes: new { @class = "control-label" })</td>
        <td class="table-header">@Html.LabelFor(model => model.AwardDate, htmlAttributes: new { @class = "control-label" })</td>
        <td class="table-header">@Html.LabelFor(model => model.AwardValue, htmlAttributes: new { @class = "control-label" })</td>
    </tr>
    <tr>
        <td>@Html.DisplayFor(model => model.PoId, new { htmlAttributes = new { @class = "form-control" } })</td>
        <td>@Html.DisplayFor(model => model.VendorName, new { htmlAttributes = new { @class = "form-control" } })</td>
        <td>@Html.DisplayFor(model => model.AwardDate, new { htmlAttributes = new { @class = "form-control" } })</td>
        <td>@Html.DisplayFor(model => model.AwardValue, new { htmlAttributes = new { @class = "form-control" } })</td>
    </tr>
    <tr>
        <td class="table-header">@Html.LabelFor(model => model.CloseDate, htmlAttributes: new { @class = "control-label" })</td>
        <td class="table-header" ">@Html.LabelFor(model => model.FinalValue, htmlAttributes: new { @class = "control-label" })</td>
        <td class="table-header" ">@Html.LabelFor(model => model.ServiceRep, htmlAttributes: new { @class = "control-label" })</td>
    </tr>
    <tr>
        <td>@Html.DisplayFor(model => model.CloseDate, new { htmlAttributes = new { @class = "form-control" } })</td>
        <td>@Html.DisplayFor(model => model.FinalValue, new { htmlAttributes = new { @class = "form-control" } })</td>
        <td>@Html.DisplayFor(model => model.ServiceRep, new { htmlAttributes = new { @class = "form-control" } })</td>
    </tr>
</table>
<div id="sections">
    @{
        if(Model.Sections != null) {
            @Html.EditorFor(model => model.Sections)

        }
    }

RatingSectionModel.cshtml:

@model List<VendorRating.Models.RatingSectionModel>

@{
    var id = "";

    foreach(VendorRating.Models.RatingSectionModel sectionModel in Model) {
        using(Html.BeginCollectionItem("Sections", out id)) {

            <fieldset style="margin-top:10px;">
                <legend style="font-weight:bold;">
                    @sectionModel.SectionName
                    @Html.HiddenFor(model => sectionModel.SectionId)
                </legend>
                <div style="display:table;width:100%">

                    @foreach(VendorRating.Models.RatingCategoryModel c in sectionModel.RatingCategories) {
                        @Html.EditorFor(cat => c);
                    }
                    <div style="display:table-row;width:100%">
                        <div style="display:table-cell;width:70%"></div>
                        <div style="display:table-cell;text-align:right;width:10%"></div>
                        <div style="display:table-cell;text-align:right;width:10%">Total</div>
                        <div style="display:table-cell;text-align:right;width:10%;"><div data-section-total="@sectionModel.SectionId" style="width:50%;border-bottom:solid 1px lightgray;text-align:right;"></div></div>
                    </div>
                </div>
            </fieldset>
            <script>
                function changeTotals() {
                    var totalScore = 0;
                    $('#poForm').find('*[data-section-score="@sectionModel.SectionId"]').each(function () {
                        var val = parseFloat($(this).text());

                        if (!isNaN(val)) {
                            totalScore = totalScore + val;
                        }
                    });

                    $('#poForm').find('*[data-section-total="@sectionModel.SectionId"]').text(totalScore);
                }
            </script>
        }
    }
}

字段生成正确,但是当我检查表单时,每个字段的名称是 Sections[sectionid here].sectionModel.FieldName。在提交表单时,插入名称中的 sectionModel 会阻止它与 Sections 集合正确绑定。适当数量的部分被添加到集合中,但它们的所有属性都是空的。我确定我在这里设置了一些错误,但我不知道它可能是什么。

【问题讨论】:

  • id 值不用于绑定 - 它们不提交给服务器。 name html 属性是 Request.Form 集合中的键,绑定使用它们。
  • 谢谢。我是说名字。现在已经更正了。
  • 完美!将 foreach 更改为 for 并删除 BeginCollectionItem,它可以完美运行。 @DanielGpeReyes,如果您将其作为答案提交,我很乐意接受并投票。
  • 尽管接受了答案,但真正的问题是您不理解EditorTemplateRatingSectionModel.cshtml 应该是 @model RatingSectionModel(不是 List&lt;T&gt;)。 EditorFor() 接受 IEnumerable&lt;T&gt; 并根据集合中每个项目的模板呈现 html。此外,您无需先检查null。它只是@Html.EditorFor(m =&gt; m.RatingSections)(我认为Sections 是一个错字)
  • 感谢您提供的信息。我以前看到过,但是当我尝试以这种方式编写代码时,它抛出了一个异常,指出该模型不是 IEnumerable。我确定我做错了什么,但在这个特定的项目上,我没有时间回去探索它。

标签: c# asp.net asp.net-mvc asp.net-mvc-4 razor


【解决方案1】:

您应该将您的 foreach 更改为 for,绑定将起作用!

【讨论】:

    猜你喜欢
    • 2011-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-18
    • 1970-01-01
    • 1970-01-01
    • 2010-11-18
    • 1970-01-01
    相关资源
    最近更新 更多