【问题标题】:Passing a list to partialview, BeginCollectionItem()将列表传递给部分视图,BeginCollectionItem()
【发布时间】:2015-11-14 14:13:50
【问题描述】:

我想将一个列表传递给具有 BeginCollectionItem() 的 PartialView。这是代码,

InquiryOrderViewModel

public class InquiryOrderViewModel
{
    public InquiryOrder InquiryOrder { get; set; }
    public List<InquiryOrderDetail> InquiryOrderDetails { get; set; }
    public List<InquiryComponentDetail> InquiryComponentDetails { get; set; }        
}

InquiryComponentDetail型号

public class InquiryComponentDetail
{
    [Key]
    public int InquiryComponentDetailId { get; set; }

    public int DesignCodeId { get; set; }

    public int QualityReferenceId { get; set; }

    public int Height { get; set; }

    public int Length { get; set; }

    public int GscmComp { get; set; }

    public int Wastage { get; set; }

    public int TotalYarn { get; set; }

    public virtual DesignCodeQltyRef DesignCodeQltyRef { get; set; }

}

InquiryOrderIndex 一次渲染多个项目的视图和脚本

@model eKnittingData.InquiryOrderViewModel 

@using (Html.BeginForm("Save", "InquiryOrder"))
{
..........
<div id="cmpDts">
  @foreach (var item in Model.InquiryComponentDetails)
    {

    }
</div>
..........
}

<script>
        var prev;
        $(document).on('focus', '.class03', function () {
            prev = $(this).val();
        }).on('change', '.class03', function () {
            if (prev != "") {
                $.ajax({
                    url: '@Url.Action("ComponentDts", "InquiryOrder")', // dont hard code your url's
                    type: "GET",
                    data: { DesignCdId: $(this).val() }, // pass the selected value
                    success: function (data) {
                        $('.cmpCls').last().replaceWith(data);
                    }
                }); 
            }
            else {
                $.ajax({
                    url: '@Url.Action("ComponentDts", "InquiryOrder")', // dont hard code your url's
                    type: "GET",
                    data: { DesignCdId: $(this).val() }, // pass the selected value
                    success: function (data) {
                            $(".class03 option[value='']").remove();
                            $('#cmpDts').append(data);
                    }
                });
            }
        });
        </script>

_DetailEditorRow PartialView 为 ddls 提供class03 并在主视图中附加了它。(这只是为了向您展示class03 是什么)

@model eKnittingData.InquiryOrderDetail
@using eKnitting.Helpers

@using (Html.BeginCollectionItem("InquiryOrderDetails"))
{
<div class="editorRow">
    @Html.DropDownListFor(a => a.ComponentId, (SelectList)ViewBag.CompList, "Select", new { Class = "class02" })
    @Html.DropDownListFor(a => a.DesignCodeId, (SelectList)ViewBag.DCodeList, "Select", new { Class = "class03" })
    @Html.TextBoxFor(a => a.NoOfParts, new { Class = "class01" })
    <a href="#" class="deleteRow">delete</a>
</div>
}

and in main view it got appended to 

<div id="editorRows">         
            @foreach (var item in Model.InquiryOrderDetails)
            {
                Html.RenderPartial("_DetailEditorRow", item);
            }           
    </div>

_ComponentDetailsPartialView 来渲染项目(一个列表一次传过)

@model List<eKnittingData.InquiryComponentDetail>
@using eKnitting.Helpers

<div class="cmpCls">
@foreach(var icd in Model)
{
    using (Html.BeginCollectionItem("InquiryComponentDetails"))
    {
    <div class="innerCmpCls">
        @Html.DisplayFor(a => icd.DesignCodeId)
        @Html.DisplayFor(a => icd.QualityReferenceId)            
        @Html.TextBoxFor(a => icd.Height, new { Class="clsHeight clsSameHL"})
        @Html.TextBoxFor(a => icd.Length, new { Class = "clsLength clsSameHL" }) 
        @Html.TextBoxFor(a => icd.GscmComp, new { Class = "clsGscmComp clsSameHL" })
        @Html.TextBoxFor(A => icd.Wastage, new { Class = "clsWastage" })
        @Html.ActionLink("Fds", "View", new { id = icd.QualityReferenceId }, new { @class = "myLink", data_id = icd.QualityReferenceId })
        @Html.TextBoxFor(a => icd.TotalYarn, new { Class = "clsTotalYarn" })
        <br>
        <div class="popFds"></div>
    </div>
    }
}
</div> 

一次传递一个列表并返回PartialView的ActionResult

    public ActionResult ComponentDts(int DesignCdId)
    {
        var objContext = new KnittingdbContext();
        var QltyRefList = objContext.DesignCodeQltyRefs.Where(a=>a.DesignCodeId==DesignCdId).ToList();

        var iocdList = new List<InquiryComponentDetail>();

        foreach(DesignCodeQltyRef dcqr in QltyRefList)
        {
            iocdList.Add(new InquiryComponentDetail { 
                DesignCodeId=dcqr.DesignCodeId,
                QualityReferenceId=dcqr.QltyRefId
            });
        }
        return PartialView("_ComponentDetails", iocdList);
    }

GET 的操作结果

        var objContext = new KnittingdbContext();

        var newIovm = new InquiryOrderViewModel();
        var newIo = new InquiryOrder();
        var iocdL = new List<InquiryComponentDetail>();

        newIovm.InquiryOrder = newIo;
        newIovm.InquiryComponentDetails = iocdL;

        return View(newIovm);

POST 的操作结果

public ActionResult Save(InquiryOrderViewModel inquiryOrderViewModel)
{
    .........
}

当用户从下拉列表(class03) 中选择一个项目时,与该项目相关的项目将使用 PartialView(_ComponentDetails') 呈现到视图并附加。然后用户从另一个 ddl(class03) 中选择另一个项目,相关项目在之前附加的项目之后被渲染和附加。用户可以这样继续下去。

渲染和附加项目工作正常。但是对于 PostBack,即使我正确获取了列表中的项目数(我通过在 POST ActionResult 上放置一个断点来检查它)所有项目内容都显示空值。请以正确的方式指导我实现这一目标。所有帮助表示赞赏。谢谢!

【问题讨论】:

  • 一些没有意义的事情 - @foreach (var item in Model.InquiryComponentDetails) { Html.RenderPartial("_ComponentDetails",item); } 正在将 InquiryComponentDetail 的实例传递给 _ComponentDetails.cshtml 部分视图,但该视图需要 List&lt;InquiryComponentDetail&gt;,因此代码会抛出一个例外。您的脚本使用 class="class03" 引用元素,但您的代码未显示任何具有该类名称的元素 - 即您没有向我们显示正确的代码。
  • @Stephen Muecke,感谢您的回复 :) 我更新了问题,现在您可以看到 class03 来自哪里。它是 ddls 的 Class。而且我在 foreach 中删除了 RenderPartial,因为我一开始没有渲染初始项目。如果有任何不清楚的事情请告诉我..
  • @Stephen Muecke,希望我提供的信息可以让您有一个清晰的想法。但如果仍然不清楚,请告诉我。我还在为这个问题苦苦挣扎
  • 还是一头雾水。 InquiryOrderViewModel 不包含 InquiryOrderDetail 类型的集合属性,因此不清楚它的用途。但是如果你的属性没有绑定,你需要为InquiryComponentDetail显示你的模型(首先要检查的是你的属性是否有getter和setter)
  • @Stephen Muecke,是的,在 viewmodel 中有一个 InquiryOrderDetail 列表。我将其从问题中删除,因为我认为它与问题无关。现在我又添加了。在InquiryComponentDetail 模型中,每个属性都有getter 和setter。我应该更新问题以显示InquiryComponentDetail 模型吗?

标签: asp.net-mvc-5 begincollectionitem


【解决方案1】:

您的_ComponentDetails 视图正在生成具有类似名称属性的表单控件(其中###Guid

name="InquiryComponentDetail[###].icd.Height"

这与您的模型不匹配,因为 typeof InquiryComponentDetail 不包含名为 icd 的属性。为了绑定到您的模型,您的 name 属性需要

name="InquiryComponentDetail[###].Height"

要生成正确的 html,您需要 2 个部分

_ComponentDetailsList.cshtml(这将由使用return PartialView("_ComponentDetailsList", iocdList);ComponentDts()方法调用)

@model List<eKnittingData.InquiryComponentDetail>
<div class="cmpCls">
  @foreach(var item in Model)
  {
    Html.RenderPartial("_ComponentDetails", item);
  }
</div>

_ComponentDetails.cshtml

@model eKnittingData.InquiryComponentDetail
using (Html.BeginCollectionItem("InquiryComponentDetails"))
{
  <div class="innerCmpCls">
    @Html.DisplayFor(a => a.DesignCodeId)
    @Html.DisplayFor(a => a.QualityReferenceId)            
    @Html.TextBoxFor(a => a.Height, new { @class="clsHeight clsSameHL"}) // use @class, not Class
    @Html.TextBoxFor(a => a.Length, new { Class = "clsLength clsSameHL" }) 
    ....
  </div>
}

【讨论】:

  • 是的,它成功了!你为我花了很多时间。非常感谢:) 最后你能告诉我如何在_ComponentDetails.cshtml 视图中经过上述修改@Html.ActionLink("Fds", "View", new { id = icd.QualityReferenceId }, new { @class = "myLink", data_id = icd.QualityReferenceId }) 后设置id 吗?
  • 应该只是new { id = Model.QualityReferenceId }data_id = Model.QualityReferenceId
  • 好的.. 非常感谢:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-16
  • 1970-01-01
  • 2012-02-02
相关资源
最近更新 更多