2017-09-19 16 views
1

我将动态项目添加到查询表单。使用部分视图来添加/删除项目,但在提交主视图时,值不受限制。我的问题是如何做同样的事情。使用ViewModel不起作用将动态添加的部分视图数据提交给控制器

已经检查了几个类似的问题herehere但找不到遗漏的东西。

使用2 ViewModels,主视图(查询)和部分视图(LineItems),并使用BeginCollectionItem动态添加项目。

代码:

的ViewModels

public class EnquiryVM 
    { 
     public int ID { get; set; } 

     [Required] 
     public string EnquiryNumber { get; set; } 
     public int ClientID { get; set; } 
     public IEnumerable<SelectListItem> Clients { get; set; } 
     public Client Client { get; set; } 
     public int ItemID { get; set; } 
     public List<EnquiryLineItem> LineItems { get; set; } 

    } 
public class EnquiryLineItemVM 
    { 
     public int ID { get; set; } 
     [Required] 
     public string ItemDesc { get; set; } 
     public int Quantity { get; set; } 
     public int ManufacturerId { get; set; } 
     public IEnumerable<SelectListItem> ManufacturerList { get; set; } 
    } 

查看: 主:

@model ViewModel.EnquiryVM 

@using (Html.BeginForm("Create", "Enquiries", FormMethod.Post)) 
{ 
    @Html.AntiForgeryToken() 

    <div class="form-horizontal"> 

     <hr /> 
     @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 



     <div class="form-group"> 
      @Html.LabelFor(model => model.EnquiryNumber, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-3"> 
       @Html.EditorFor(model => model.EnquiryNumber, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.EnquiryNumber, "", new { @class = "text-danger" }) 
      </div> 
     </div> 





     <div class="form-group"> 
      @Html.LabelFor(model => model.ClientID, "Client", htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-3"> 

       @Html.DropDownListFor(u => u.ClientID, (IEnumerable<SelectListItem>)Model.Clients, "--Select--") 
       @Html.ValidationMessageFor(model => model.ClientID, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

     <div id="LineItems"> 
      // @using (Html.BeginForm()) // do we require again here since this will be like nested form? tested commenting still not working 
      // { 
       <div id="editorRowsLineitems"> 
        @foreach (var item in Model.LineItems) 
        { 
         @Html.Partial("_CreateEnquiryItem", item) 
        } 
       </div> 
       @Html.ActionLink("Add Items", "CreateLineItem", null, new { id = "addItem", @class = "button" }); 
      // } 
     </div> 
     <div class="form-group"> 
      <div class="col-md-offset-2 col-md-10"> 
       <input type="submit" value="Create" class="btn btn-default" /> 
      </div> 
     </div> 
    </div> 
} 

<div> 
    @Html.ActionLink("Back to List", "Index") 
</div> 

@section Scripts { 
    @Scripts.Render("~/bundles/jqueryval") 
<script type="text/javascript"> 
    $(function() { 
     $('#addItem').on('click', function() { 
      $.ajax({ 
       url: '@Url.Action("CreateLineItem")', 
        cache: false, 
        success: function (html) { 
         $("#editorRowsLineitems").append(html); 

         $("form").removeData("validator"); 
         $("form").removeData("unobtrusiveValidation"); 
         $.validator.unobtrusive.parse("form"); 
        } 
       }); 
       return false; 
      }); 
     $('#editorRowsLineitems').on('click', '.deleteRow', function() { 
       $(this).closest('.editorRow').remove(); 
      }); 
     $('form').data('validator', null); 
     $.validator.unobtrusive.parse($('form')); 
    }); 


</script> 
} 

局部视图:

@model ViewModels.EnquiryLineItemVM 

<div class="editorRow"> 
    @using (Html.BeginCollectionItem("ItemList")) 
    { 
     <table class="table"> 

      <tr> 
       <td> 
        @Html.EditorFor(model => model.ItemDesc) 

       </td> 
       <td> 
        @Html.EditorFor(model => model.Quantity) 

       </td> 

       <td> 
        @Html.DropDownListFor(model => model.ManufacturerId, Model.ManufacturerList, "--Please Select--") 

       </td> 
       <td> 

        <a href="#" class="deleteRow">Delete</a> 
       </td> 
      </tr> 
     </table> 

    } 

控制器:

public ActionResult Create() 
     { 
      var viewModel = GetAllCategories(); 
      return View(viewModel); 
     } 
    private EnquiryVM GetAllCategories() 
     { 
      var model = new EnquiryVM(); 
      var clients = db.Clients.ToList(); 
      model.Clients = clients.Select(s => new SelectListItem 
      { 
       Value = s.ID.ToString(), 
       Text = s.Name 
      }); 

      var LineItems = new List<EnquiryLineItem>(); 
      model.LineItems = LineItems; 

      return model; 
     } 
[HttpPost] 
     [ValidateAntiForgeryToken] 
     public ActionResult Create(EnquiryVM enquiryVM) 
     { 
      var enquiry = new Enquiry(); 
      enquiry.EnquiryNumber = enquiryVM.EnquiryNumber; 
      enquiry.ClientID = enquiryVM.ClientID; 
      enquiry.EnquiryLineItems = enquiryVM.LineItems; //line items are null 
      if (ModelState.IsValid) 
      { 
       db.Enquiries.Add(enquiry); 
       enquiryVM.ID = enquiry.ID; 
       foreach (var item in enquiry.EnquiryLineItems) 
       { 
        item.EnquiryID = enquiryVM.ID; 
        db.EnquiryLineItems.Add(item); 
       } 

       db.SaveChanges(); 
       return RedirectToAction("Index"); 
      } 

      var viewModel = GetAllCategories(); 
      return View(enquiryVM); 
     } 

我该如何将动态添加的行的值映射到ViewModel(EnquiryVM),以便我可以将其插入到数据库中。 感谢您的耐心和时间。

回答

1

您的集合属性的名称是LineItems,因此代码以产生其控制需要是

@using (Html.BeginCollectionItem("LineItems")) // not ..("ItemList") 
{ 
    .... 
} 

,使得它生成输入与name="LineItems[xxxx].ItemDesc"等,而不是为产生name="ItemList[xxxx].ItemDesc"当前使用(其中xxxxGuid

作为一个方面说明,如果ModelState无效,则POST方法中的代码将引发异常,因为您返回视图并且未重新填充IEnumerable<SelectListItem> Clients属性。有关详细说明,请参阅The ViewData item that has the key 'XXX' is of type 'System.Int32' but must be of type 'IEnumerable'

此外,您的脚本的最后2行添加项目($('form').data('validator', null); $.validator.unobtrusive.parse($('form'));应该被删除(重新分析验证程序是昂贵的,你做了两次 - 一次在你添加html(上面的2行)和一次后添加html

+0

另请参阅编辑(最后一段) –

+0

谢谢斯蒂芬现在我得到了你想要指出的关于上一个问题中的集合属性,我只改变了它的一个地方,但忘记了与属性名称匹配但是你的解释有助于了解BCI是如何工作的以及它是如何应用的 – user2695433

+0

我会尽快解答你的其他问题(希望):) –

相关问题