여러 번 호출 된 동일한 부분 뷰 데이터를 컨트롤러에 제출

asp.net-mvc-4


내보기에 버튼을 추가했습니다. 이 버튼을 클릭하면 부분보기가 추가됩니다. 내 양식에서 나는 가능한 한 많은 부분보기를 추가 할 수 있습니다. 이 양식 데이터를 제출할 때 모든 부분보기 데이터를 컨트롤러로 보낼 수 없습니다. 모든 속성을 가진 다른 모델을 만들었으며 해당 모델 목록을 기본 모델로 만들었습니다. 누구나 일부 부분보기 내용을 컨트롤러에 보낼 수 있도록 트릭을 줄 수 있습니까?

내 관점에서

<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");
    }
  });
}

내 컨트롤러에서

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)
{
  ....
}

내 부분보기에서

@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>




Answer 1 Community


문제는 부분적으로 단일 AdminProductDetailModel 객체를 기반으로 html을 렌더링 하지만 컬렉션을 다시 게시하려고한다는 것입니다. 새 객체를 동적으로 추가 할 때 <input name="productTotalQuantity" ..> (이것은 중복 id 속성으로 인해 유효하지 않은 HTML을 생성 함) 처럼 보이는 <input name="[0].productTotalQuantity" ..> , <input name="[1].productTotalQuantity" ..> 등을 통해 포스트 백에서 콜렉션에 바인드합니다.

DefaultModelBinder 는 수집 항목 인덱서는 0에서 시작하고 연속적 일 또는 양식 값이 포함되어 있다는 것이 요구 Index=someValue 인덱서는 someValue 와 (예를 들어 <input name="[ABC].productTotalQuantity" ..><input name="Index" value="ABC"> 이 내용은 Phil Haack 기사 Model Binding to A List 에 자세히 설명되어 있지만 일반적으로 Index 접근 방식을 사용하면 목록에서 항목을 삭제할 수 있으므로 더 좋습니다. 인덱서가 연속적이므로 모든 기존 컨트롤의 이름을 바꾸는 데 필요합니다.

문제에 대한 두 가지 가능한 접근 방식.

옵션 1

부분보기에 BeginItemCollection 도우미를 사용하십시오 . 이 도우미는 GUID를 기반으로 Index 값에 대한 숨겨진 입력을 렌더링합니다 . 기존 항목을 렌더링하는 부분보기와 루프 모두에서이를 필요로합니다. 당신의 부분은 다음과 같이 보일 것입니다

@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

'가짜'인덱서를 사용하여 새 객체를 나타내는 html 요소를 수동으로 작성하고 숨겨진 컨테이너에 배치 한 다음 추가 단추 이벤트에서 html을 복제하고 인덱서 및 색인 값을 업데이트하고 복제 된 요소를 DOM에 추가하십시오. html이 올바른지 확인하려면 for 루프 에서 하나의 기본 객체를 만들고 생성 된 html을 검사하십시오. 이 접근법의 예가이 답변에 나와 있습니다.

<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>

포스트 백에 바인딩되는 것을 방지하기 위해 '가짜'인덱서를 사용하십시오 ( '#'와 '%'는 일치하지 않으므로 DefaultModelBinder 에 의해 무시됩니다 )

$('#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에 새 요소를 추가 할 때마다 유효성 검사기를 다시 구문 분석해야합니다 .

$('form').data('validator', null);
$.validator.unobtrusive.parse($('form'));

물론 컬렉션을 수락하려면 POST 메소드를 변경해야합니다.

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