首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >向控制器提交多次调用的相同部分视图?

向控制器提交多次调用的相同部分视图?
EN

Stack Overflow用户
提问于 2015-01-19 15:29:54
回答 1查看 26.8K关注 0票数 27

我在我的视图中添加了一个按钮。单击此按钮时,将添加局部视图。在我的表单中,我可以添加尽可能多的局部视图。提交此表单数据时,我无法将所有部分视图数据发送到控制器。我制作了一个具有所有属性的不同模型,并将该模型的列表添加到我的主模型中。谁能给我一些技巧,让我可以发送所有的部分视图内容到我的控制器?

在我的视图中

代码语言:javascript
复制
<div id="CSQGroup">   
</div>
<div>
  <input type="button" value="Add Field" id="addField" onclick="addFieldss()" />
</div>

function addFieldss()
{    
  $.ajax({
    url: '@Url.Content("~/AdminProduct/GetColorSizeQty")',
    type: 'GET',
    success:function(result) {
      var newDiv = $(document.createElement("div")).attr("id", 'CSQ' + myCounter);  
      newDiv.html(result);
      newDiv.appendTo("#CSQGroup");
      myCounter++;
    },
    error: function(result) {
      alert("Failure");
    }
  });
}

在我的控制器中

代码语言:javascript
复制
public ActionResult GetColorSizeQty()
{
  var data = new AdminProductDetailModel();
  data.colorList = commonCore.getallTypeofList("color");
  data.sizeList = commonCore.getallTypeofList("size");
  return PartialView(data);
}

[HttpPost]
public ActionResult AddDetail(AdminProductDetailModel model)
{
  ....
}

在我的局部视图中

代码语言:javascript
复制
@model IKLE.Model.ProductModel.AdminProductDetailModel
<div class="editor-field">
  @Html.LabelFor(model => model.fkConfigChoiceCategorySizeId)
  @Html.DropDownListFor(model => model.fkConfigChoiceCategorySizeId, Model.sizeList, "--Select Size--")
  @Html.ValidationMessageFor(model => model.fkConfigChoiceCategorySizeId)
</div>
<div class="editor-field">
  @Html.LabelFor(model => model.fkConfigChoiceCategoryColorId)
  @Html.DropDownListFor(model => model.fkConfigChoiceCategoryColorId, Model.colorList, "--Select Color--")
  @Html.ValidationMessageFor(model => model.fkConfigChoiceCategoryColorId)
</div>   
<div class="editor-field">
  @Html.LabelFor(model => model.productTotalQuantity)
  @Html.TextBoxFor(model => model.productTotalQuantity)
  @Html.ValidationMessageFor(model => model.productTotalQuantity)
</div>
EN

回答 1

Stack Overflow用户

发布于 2015-01-22 12:28:58

您的问题是,部分呈现基于单个AdminProductDetailModel对象的html,而您却试图回发一个集合。当您动态添加一个新对象时,您会继续添加类似于<input name="productTotalQuantity" ..>的重复控件(这也会因为重复的id属性而创建无效的html ),因为它们需要是<input name="[0].productTotalQuantity" ..><input name="[1].productTotalQuantity" ..>等,以便在回发时绑定到集合。

DefaultModelBinder要求集合项的索引器从零开始并且是连续的,或者表单值必须包括索引器为someValueIndex=someValue (例如<input name="[ABC].productTotalQuantity" ..><input name="Index" value="ABC">。这在Phil Haack的文章Model Binding To A List中有详细的解释。使用Index方法通常更好,因为它还允许您从列表中删除项(否则必须重命名所有现有控件,以便索引器是连续的)。

两种可能的方法来解决你的问题。

选项1

对局部视图使用BeginItemCollection帮助器。此辅助对象将根据GUID呈现Index值的隐藏输入。在局部视图和呈现现有项的循环中都需要它。你的片断看起来像这样

代码语言:javascript
复制
@model IKLE.Model.ProductModel.AdminProductDetailModel
@using(Html.BeginCollectionItem()) 
{
  <div class="editor-field">
    @Html.LabelFor(model => model.fkConfigChoiceCategorySizeId)
    @Html.DropDownListFor(model => model.fkConfigChoiceCategorySizeId, Model.sizeList, "--Select Size--")
    @Html.ValidationMessageFor(model => model.fkConfigChoiceCategorySizeId)
  </div>
  ....
}

选项2

手动创建用'fake‘索引器表示新对象的html元素,将它们放在一个隐藏的容器中,然后在Add按钮事件中,克隆html,更新indexers和Index值,并将克隆的元素附加到DOM。为了确保html是正确的,在for循环中创建一个默认对象并检查它生成的html。此方法的一个示例显示在this answer

代码语言:javascript
复制
<div id="newItem" style="display:none">

  <div class="editor-field">
    <label for="_#__productTotalQuantity">Quantity</label>
    <input type="text" id="_#__productTotalQuantity" name="[#].productTotalQuantity" value />
    ....
  </div>
  // more properties of your model
</div>

注意使用了'fake‘索引器来防止在回发时绑定这个索引器('#’和'%‘不匹配,所以它们会被DefaultModelBinder忽略)

代码语言:javascript
复制
$('#addField').click(function() {
  var index = (new Date()).getTime(); 
  var clone = $('#NewItem').clone();
  // Update the indexer and Index value of the clone
  clone.html($(clone).html().replace(/\[#\]/g, '[' + index + ']'));
  clone.html($(clone).html().replace(/"%"/g, '"' + index  + '"'));
  $('#yourContainer').append(clone.html());
}

选项1的优点是,您将视图强输入到模型中,但这意味着每次添加新项时都要调用服务器。选项2的优点是它完全是客户端的,但是如果你对你的模型做了任何改变(例如,给属性添加一个验证属性),那么你还需要手动更新html,这使得维护变得有点困难。

最后,如果使用客户端验证(jquery-validate-unobtrusive.js),则每次向DOM添加新元素时都需要重新解析验证器,如this answer中所述。

代码语言:javascript
复制
$('form').data('validator', null);
$.validator.unobtrusive.parse($('form'));

当然,您还需要更改POST方法以接受集合

代码语言:javascript
复制
[HttpPost]
public ActionResult AddDetail(IEnumerable<AdminProductDetailModel> model)
{
  ....
}
票数 54
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28019793

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档