【问题标题】:Dynamic partial view list not being picked up when saving保存时未拾取动态局部视图列表
【发布时间】:2016-03-24 12:25:48
【问题描述】:

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

<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 属性?我应该尝试改用编辑器模板吗?

【问题讨论】:

  • 您不能将EditorTemplateBeginCollectionItem() 一起使用。并从您的零件中删除脚本。你 foreach 循环没有意义 - 我认为它的意思是 @Html.Partial("budgetdetail", budgetdetail) 但如果到那一步,else 会抛出异常

标签: asp.net-mvc-4


【解决方案1】:

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

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

  @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 视图从主视图调用模板。

这是来自主视图的调用:

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

这是中间的 IEnumerable 视图:

  @model IEnumerable<BudgetPortalMVC4.Models.budgetdetail>

 @{
Layout = null;
  }

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

希望这有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多