保存时未捕获动态部分视图列表

时间:2016-03-23 07:13:27

标签: asp.net-mvc-4

我有一个部分视图,使用此代码在我的主视图中呈现

<div>
    <h3>Budget Detail</h3>
    <div><input type="button" id="addbudgetdetail" value="Add row" /></div>
    <div id="new-budgetdetail">
        @if (Model.budget != null)
        {
            foreach (var budgetdetail in Model.budget.budgetdetails)
            {
                @Html.Partial("budgetdetail", Model)
            }
        }
        else 
        { 
            @Html.Partial("budgetdetail", Model)

        }
    </div>
</div>

有一个java脚本可以在单击按钮时动态添加更多部分视图

$(function () {
    $('#addbudgetdetail').on('click', function () {
        jQuery.get('@Url.Action("budgetdetail")').done(function (html) {
            $('#new-budgetdetail').append(html);
            $('form').data('validator', null);
            $.validator.unobtrusive.parse($('form'));
        });
    });
});

这是我的部分观点:

@model BudgetPortalMVC4.Models.NewBudgetModel
@{
    Layout = null;
}
 <script src="../../Scripts/jquery.validate.js" type="text/javascript"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"     type="text/javascript"></script>
@using (Html.BeginCollectionItem(""))
{
    @Html.ValidationSummary(true) 
    <div class="item">
        <table>
            <tr>
                <td>
                    @Html.LabelFor(m => m.SelectedCategory)
                    @Html.DropDownListFor(m => m.SelectedCategory, Model.CategoriesList, "Please select", new { @class = "SelectedCategory" })
                    @Html.ValidationMessageFor(m => m.SelectedCategory)
                </td>
                <td>
                    @Html.LabelFor(m => m.SelectedSubCategory)
                    @Html.DropDownListFor(m => m.SelectedSubCategory, Model.SubCategoriesList, "Please select", new { @class =  "SelectedSubCategory" })
                    @Html.ValidationMessageFor(m => m.SelectedSubCategory)
                </td>
                <td>
                    @Html.LabelFor(model => model.budgetdetail.Amount)              
                    @Html.EditorFor(model => model.budgetdetail.Amount)
                    @Html.ValidationMessageFor(model => model.budgetdetail.Amount)
                </td>
                <td><a href="#" id="deleteRow" class="deleteRow">Delete</a</td>
            </tr>
        </table>
    </div>
}

我的问题是,当我点击提交时,我看不到任何部分视图的列表。 我只能看到直接来自我的主视图的数据。

我在某个地方错过了IEnumerable属性吗?我应该尝试使用编辑器模板吗?

1 个答案:

答案 0 :(得分:0)

我已经解决了这个问题。我不得不重新设计模型,而不是使用分组预算和预算细节的大模型,我使用2个模型用于预算,1个用于预算细节。

我还重写了下拉列表以符合新模式:

  @Html.LabelFor(m => m.category)
            @Html.DropDownListFor(m => m.idCategory, new SelectList(ViewBag.CategoriesList, "idCategory", "CategoryName"), "Please select", new { @class = "SelectedCategory" })
            @Html.ValidationMessageFor(m => m.idCategory)


  @Html.LabelFor(m => m.subcategory)
            @Html.DropDownListFor(m => m.idSubcategory, new SelectList(ViewBag.SubCategoriesList, "Value", "Text"), "Please select", new { @class = "SelectedSubCategory" })
             @Html.ValidationMessageFor(m => m.idSubcategory)

我没有使用局部视图,而是创建了一个编辑器模板。根据Stephen的建议,BeginCollection不能在编辑器模板中使用,我使用了一个html帮助器来创建我的集合中的唯一项目。

这是助手的代码:

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
using System.Web.Mvc;
using System.Web.Mvc.Html;

namespace BudgetPortalMVC4.Extensions
{

public static class HtmlHelperExtensions
{
    public static MvcHtmlString EditorForMany<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, IEnumerable<TValue>>> expression, string htmlFieldName = null) where TModel : class
    {
        var items = expression.Compile()(html.ViewData.Model);
        var sb = new StringBuilder();

        if (String.IsNullOrEmpty(htmlFieldName))
        {
            var prefix = html.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix;

            htmlFieldName = (prefix.Length > 0 ? (prefix + ".") : String.Empty) + ExpressionHelper.GetExpressionText(expression);
        }

        foreach (var item in items)
        {
            var dummy = new { Item = item };
            var guid = Guid.NewGuid().ToString();

            var memberExp = Expression.MakeMemberAccess(Expression.Constant(dummy), dummy.GetType().GetProperty("Item"));
            var singleItemExp = Expression.Lambda<Func<TModel, TValue>>(memberExp, expression.Parameters);

            sb.Append(String.Format(@"<input type=""hidden"" name=""{0}.Index"" value=""{1}"" />", htmlFieldName, guid));
            sb.Append(html.EditorFor(singleItemExp, null, String.Format("{0}[{1}]", htmlFieldName, guid)));

        }

        return new MvcHtmlString(sb.ToString());
    }
 }
}

现在我使用中间IEnumerable视图从main调用模板。

这是来自主视图的电话:

@Html.EditorForMany(x => x.budgetdetails)

这是中间IEnumerable视图:

  @model IEnumerable<BudgetPortalMVC4.Models.budgetdetail>

 @{
Layout = null;
  }

  @Html.EditorForMany(x => x, "budgetdetails")

希望这有用。