本文介绍了嵌套的 BeginCollectionItem的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Steve Sanderson 的 BeginCollectionItem 方法来添加动态内容.当我在第一级做这件事时,一切正常.但是,当尝试在另一个 BeginCollectionItem 中实现意味着一个 BeginCollectionItem 的嵌套集合时,它似乎不起作用.

我的模型如下:

公共类订单{[钥匙][隐藏输入]公共 int id { 获取;放;}[Display(Name = "订单号")]公共字符串编号 { 获取;放;}...[Display(Name = "付款方式")]公共列表<PaymentMethod>支付方法{得到;放;}...}公共类支付方法{公共 MethodOfPayment 方法 { 获取;放;}公共抄送抄送{得到;放;}公共现金现金{得到;放;}公共 TT tt { 得到;放;}}公开课TT{[钥匙]公共 int id { 获取;放;}[必需(ErrorMessage ={0} 是必需的.")][Display(Name = "总金额")]公双?total_value { 得到;放;}...[显示(名称=转移")]公共列表<传输>转移{得到;放;}}公开课转学{[钥匙]公共 int id { 获取;放;}[显示(名称=付款")]公共 int payment_id { 获取;放;}[必需(ErrorMessage ={0} 是必需的.")][显示(名称 =SWIFT")]公共字符串 swift { 获取;放;}[必需(ErrorMessage ={0} 是必需的.")][Display(Name = "转账金额")]公双?transfer_amount { 得到;放;}[必需(ErrorMessage ={0} 是必需的.")][Display(Name = "Date Transfer")]公共日期时间 transfer_date { 获取;放;}...}

现在我有一个订单,它可以有多种付款方式,如果其中一种付款方式是 TT(电传转账),则可能涉及多次转账.在一个订单中实现多种付款方式作为集合有效,但是当我尝试在 TT 内实现多次转账时,这些转账都没有传递给控制器​​.

这是我的观点:

@model prj.Models.Model.Order@using (Html.BeginForm("Create")){@Html.ValidationSummary(true, "创建失败.请更正错误并重试.")[email protected](m => m.number, new { id = "txtnumber" })...<div id="editorPaymentRows">@foreach(Model.payment_methods 中的 var 付款){@Html.Partial("_NewPayment", 付款)}

}

在_NewPayment 部分:

@using prj.Helpers@model prj.Models.Model.PaymentMethod<div class="editPaymentRow">@using (Html.BeginCollectionItem("payment_methods")){...<div class="editor-label">@Html.LabelFor(m => m.tt.total_value)

<div class="editor-field">@Html.TextBoxFor(m => m.tt.total_value)

...<div id="editorTransferRows">@if (Model.tt != null){foreach(Model.tt.transfers 中的 var 转移){@Html.Partial("_NewTransfer", transfer)}}...

}

最后在 _NewTransfer 部分:

@using prj.Helpers@model prj.Models.Model.Transfer...<div class="editTransferRow">//使用(Html.BeginCollectionItem("transfers"))@using (Html.BeginCollectionItem("tt.transfers")){...<div class="editor-label">@Html.LabelFor(m => m.swift)

<div class="editor-field">@Html.TextBoxFor(m => m.swift, new { @class = "t_swift" })

...<div class="editor-label">@Html.LabelFor(m => m.transfer_amount)

<div class="editor-field">@Html.TextBoxFor(m => m.transfer_amount, new { @class = "t_transfer_amount" })

...}

所以一切正常,除了在控制器中,PaymentMethods 的 TT 属性中的 List 传输始终为空.它没有正确传递给控制器​​.有什么我遗漏的吗?

嵌套的 BeginCollectionItem 不起作用吗?有没有我必须做的额外步骤?请说明一下.谢谢

我使用以下链接中显示的 Joe Stevens 方法计算出来:

http://www.joe-stevens.com/2011/06/06/editing-and-binding-nested-lists-with-asp-net-mvc-2/

干杯

解决方案

要获得带有 Html.BeginCollectionItem 的前缀,您可以访问 ViewData.TemplateInfo.HtmlFieldPrefix (我正在使用 nuget 包).您使用 tt.transfers 走在正确的轨道上,但您需要使用特定的前缀.

而不仅仅是

Html.BeginCollectionItem("tt.transfers")

您还需要当前支付方法的前缀.

@{var paymentMethodPrefix = ViewData.TemplateInfo.HtmlFieldPrefix;}@using (Html.BeginCollectionItem(paymentMethodPrefix + ".tt.transfers"))

一个快速的测试看起来你也可以:

@using (Html.BeginCollectionItem(ViewData.TemplateInfo.HtmlFieldPrefix + ".tt.transfers"))

I'm using Steve Sanderson's BeginCollectionItem approach to add dynamic content. Everything works fine when I'm doing it on the first level. However, when try to implement a nested collection meaning a BeginCollectionItem in another BeginCollectionItem, it doesn't seem to work.

My models are as follows:

public class Order
{

        [Key]
        [HiddenInput]
        public int id { get; set; }

        [Display(Name = "Order number")]
        public string number { get; set; }

        ...

        [Display(Name = "Payment method")]
        public List<PaymentMethod> payment_methods { get; set; }

        ...
}

public class PaymentMethod
{
        public MethodOfPayment method { get; set; }
        public CC cc { get; set; }
        public CASH cash { get; set; }
        public TT tt { get; set; }
}

public class TT
{
        [Key]
        public int id { get; set; }

        [Required(ErrorMessage = "{0} is required.")]
        [Display(Name = "Total amount")]
        public double? total_value { get; set; }

        ...

        [Display(Name = "Transfers")]
        public List<Transfer> transfers { get; set; }
}

public class Transfer
{
        [Key]
        public int id { get; set; }

        [Display(Name = "Payment")]
        public int payment_id { get; set; }

        [Required(ErrorMessage = "{0} is required.")]
        [Display(Name = "SWIFT")]
        public string swift { get; set; }

        [Required(ErrorMessage = "{0} is required.")]
        [Display(Name = "Amount transferred")]
        public double? transfer_amount { get; set; }

        [Required(ErrorMessage = "{0} is required.")]
        [Display(Name = "Date transferred")]
        public DateTime transfer_date { get; set; }

        ...
}

Now what i have is an Order which could have several payment methods, and if one of the payment methods is a TT (telex transfer) it could have several transfers involved.Implementing several payment methods in one Order as a collection works, but when I try to implement several transfers within a TT, nothing of these transfers gets passed to the controller.

Here's what my view looks like:

@model prj.Models.Model.Order

@using (Html.BeginForm("Create")){
@Html.ValidationSummary(true, "Creation was unsuccessful. Please correct the errors and try again.")

...

@Html.TextBoxFor(m => m.number, new { id = "txtnumber" })

...


<div id="editorPaymentRows">
    @foreach (var payment in Model.payment_methods)
    {
        @Html.Partial("_NewPayment", payment)
    }
</div>

}

In the _NewPayment partial:

@using prj.Helpers
@model prj.Models.Model.PaymentMethod

<div class="editPaymentRow">

@using (Html.BeginCollectionItem("payment_methods"))
{
...

<div class="editor-label">
    @Html.LabelFor(m => m.tt.total_value)<req>*</req>
</div>

<div class="editor-field">
    @Html.TextBoxFor(m => m.tt.total_value)
</div>

...


<div id="editorTransferRows">
   @if (Model.tt != null)
{
    foreach (var transfer in Model.tt.transfers)
    {
         @Html.Partial("_NewTransfer", transfer)
    }
}
...
</div>



}

</div>

and finally in the _NewTransfer partial:

@using prj.Helpers
@model prj.Models.Model.Transfer
...

<div class="editTransferRow">
//using (Html.BeginCollectionItem("transfers"))
@using (Html.BeginCollectionItem("tt.transfers"))
{
...

<div class="editor-label">
    @Html.LabelFor(m => m.swift)<req>*</req>
</div>

<div class="editor-field">
    @Html.TextBoxFor(m => m.swift, new { @class = "t_swift" })
</div>

...

<div class="editor-label">
    @Html.LabelFor(m => m.transfer_amount)<req>*</req>
</div>

<div class="editor-field">
    @Html.TextBoxFor(m => m.transfer_amount, new { @class = "t_transfer_amount" })
</div>

...
}

</div>

So everything works, except in the controller the List transfers which is in TT property of the PaymentMethods is always null. It's not being passed to the controller properly. Is there something i'm missing?

Does nested BeginCollectionItem not work? is there an extra step I must do?Please shed some light.Thanks


I figured it out using Joe Stevens' method shown at the following link:

http://www.joe-stevens.com/2011/06/06/editing-and-binding-nested-lists-with-asp-net-mvc-2/

Cheers

解决方案

To get the prefix with an Html.BeginCollectionItem, you can access ViewData.TemplateInfo.HtmlFieldPrefix (I'm using the nuget package). You're on the right track with tt.transfers, but you need the specific prefix instead.

Instead of just

Html.BeginCollectionItem("tt.transfers")

you'll need the prefix of the current payment_method as well.

@{
    var paymentMethodPrefix = ViewData.TemplateInfo.HtmlFieldPrefix;
}
@using (Html.BeginCollectionItem(paymentMethodPrefix + ".tt.transfers"))

and a quick test looks like you can also just:

@using (Html.BeginCollectionItem(ViewData.TemplateInfo.HtmlFieldPrefix + ".tt.transfers"))

这篇关于嵌套的 BeginCollectionItem的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-17 07:25