2013-11-21 3 views
3

내 모델에는 다양한 입력과 많은 목록이있는 매우 큰 형태의 응용 프로그램이 있습니다. 그래서 나는 서버에 완전한 모델을 보내지 않고 목록을 추가/삭제하려고 시도 할 것이다.보기에서 복잡한 mvc 모델에 동적으로 바인딩 된 요소를 바인딩

지금 여러 가지 방법을 시도했지만 깨끗한 방법을 찾지 못했습니다. 당신은 내 모델이 다음과 같이 상상할 수 있습니다.

다른 모델은 비슷하지만 목록은없는 것처럼 보입니다.

<h2>Something</h2> 
    <div id="SomethingDiv"> 
     <table id="SomethingTable"> 
      <thead> 
       <tr> 
        <th>@Html.Label("SomethingName")</th> 
        <th>@Html.Label("SomethingID")</th> 
               <th></th> 
       </tr> 
      </thead> 
      <tbody id="SomethingTableBody"> 

       @Html.EditorFor(x => x.somethingList) 

      </tbody> 
     </table> 
     <p> 
      <input type="button" name="addSomething" value="Add Something" id="AddSomething"> 
     </p> 
    </div> 

addSomething의 JQuery와는 :

$('#AddSomething').click(function() { 
     $.ajax({ 
      url: '@Url.Action("AddSomething", "SomethingModels")', 
      data: { tableSize: $('#SomethingTable tr').length }, 
      cache: false, 
      success: function (html) { $('#SomethingTable tr:last').after(html); } 
     }); 

제어기 방법 AddSomething입니다

public ActionResult AddSomething (int tableSize) 
{ 
    SomethingModel something= new SomethingModel(null, (-2) * (tableSize + 1)); 
    return PartialView(""~/Views/EditorTemplates/EditSomethingModel.cshtml"", something); 
} 

그리고 난 모델 테이블이 뷰

적어도 editorfor 및 partialview에 대한 EditorTemplates의 편집기 템플릿이 있습니다.

@model SomethingModel 
<tr>@TextBoxFor(m=>m.SomethingName)<td> 

@TextBoxFor (m => m.SomethingID)

그래서 문제가 지금의이 첫 번째보기의 제출 만 게시물 : 이것은 내가 서버에 보낼 중요한 정보를 가지고 보기를 여는 동안 이미 존재하지만 AddMutation 메소드의 새 SomethingModel이 게시물에없는 서버에 SomethingModel을 추가하십시오. 이 문제를 해결할 사람이 있습니까?

편집 : EditorForPartialView에 대해 하나의보기 만 필요하므로 편집기 템플릿의 경로가 변경되었습니다.

편집 2 : 주요 문제를 해결하기 위해 다음과 같이보기를 생성하여 부분보기로 사용합니다. 이제 데이터가 서버에 올바르게 전송됩니다. 만 클라이언트 측 유효성 검사가 여전히 작동하지 않습니다 :

@model SomethingModel 
    <tr>@TextBoxFor(m=>m.SomethingName, new{Name="somethingList["+ViewBag.ListId+"].SomethingName")<span class="field-validation-valid" data-valmsg-for="somethingList[@ViewBag.ListId].SomethingName" data-valmsg-replace="true"></span><td> 
<tr>@TextBoxFor(m=>m.SomethingID, new{Name="somethingList["+ViewBag.ListId+"].SomethingID")<span class="field-validation-valid" data-valmsg-for="somethingList[@ViewBag.ListId].SomethingID" data-valmsg-replace="true"></span><td> 
</tr> 

AddSomething 방법에서 나는 목록에서 다음 요소의 ID와 ViewBag.ListId을 추가했습니다.

+0

나는 당신에 눈에 거슬리지 검증을받을 수 있도록하기 위해 필요한 변화에 내 대답을 변경했을 : -

편집은 다음과 같이 새 필드가 JQuery와 아약스 성공 콜백을 변경하기위한 작업을 클라이언트 측 유효성 검사를 얻을 수 있습니다 ajax 콜백 후에 새 필드를 사용하십시오. –

+0

예. 볼 수 있습니다. 그러나 제출하려는 양식에서 모든 유효성 검사를 제거해야합니다. 이것은 작동합니다 : var table ='$ ('#SomethingForm'). removeData ("validator"). removeData ("unobtrusiveValidation"); $ .validator.unobtrusive.parse (table);'고맙습니다. –

답변

2

그것은 합리적인 충분히 접근 방식을 보이지만, 당신은 당신의 EditorTemplate를 표시하지, 그래서 내가 좋아하는 그 무언가를 생각하는거야 :

@model List<something> 

@for(int i = 0; i < Model.Count; i++) 
{ 
    <tr> 
    <td>@Html.DisplayFor(m => m[i].Id) @Html.HiddenFor(m => m[i].Id)</td> 
    <td>@Html.EditorFor(m => m[i].Name)</td> 
    </tr> 
} 

귀하의 아약스 방법은 행의 HTML을 반환해야합니다 - 그리고 이것은 중요합니다 ... 양식 필드는 테이블의 마지막 하나 위에 이름이 지정되어야합니다. 당신이 어떤 새로운 필드를 추가하기 전에 (테이블의 렌더링 된 소스를 볼 때처럼

그래서 보일 수 있습니다 : 당신은 당신의 새로운 행에 대한 아약스 방법에 의해 반환 된 HTML을 확인해야

... 
<tbody> 
    <tr> 
    <td>1 <input type="hidden" name="something[0].Id" value="1"/></td> 
    <td><input type="text" name="something[0].Name" value="somename" /></td> 
    </tr> 
</tbody> 

입니다 :

<tr> 
    <td>2 <input type="hidden" name="something[1].Id" value="2"/></td> 
    <td><input type="text" name="something[1].Name" value="somenewname" /></td> 
    </tr> 

즉. 괄호 안에있는 숫자는 무엇인가있는 항목에 대해 다음 인덱스입니다. 다음 새 항목이 분석되지 않습니다이 인덱스의 차이가 (또는 그들이 중복)합니다.

$('#AddSomething').click(function() { 
    $.ajax({ 
     url: '@Url.Action("AddSomething", "SomethingModels")', 
     data: { tableSize: $('#SomethingTable tr').length }, 
     cache: false, 
     success: function (html) { 
      $('#SomethingTable tr:last').after(html); 
      $.validator.unobtrusive.parse('#SomethingTable'); 
     } 
    }); 
+0

제 질문에 대한 코드가 변경되었습니다. 마지막 코드 샘플은 편집기 템플리트입니다. 나는'EditorFor'를 사용하여 somethingList의 모든 요소를 ​​보여줍니다. mvc 도우미는 목록의 각 항목에 대해 자동으로 viw를 작성하므로 루프를 사용할 필요가 없습니다. 또한 내 아약스 메서드는 행의 HTML을 반환했지만 귀하의 권리, 그것은 목록에서 numeration을 사용하지 마십시오. ''대신 ''으로 만 생성됩니다. '. 그 뒷모습에 대해 고마워, 내가 어떻게 바꿀 수 있는지 확인해. –

+0

@James 인덱스에 간격이있는 경우 동적 html을 제거하는 마이너스 버튼이 있기 때문에 전체 컬렉션을 어떻게 파싱 할 수 있습니까? – Zinov

+0

@ Zinov 제거한 것보다 나중에 모든 필드를 다시 색인하려면 자바 스크립트가 필요합니다. 클라이언트 측 필드 인덱스에 갭을 둘 수 없거나 포스트 백에서 파싱되지 않습니다. 예를 들어 ''그런 다음 행을 제거하고 더 높은 색인을 가진 행 모음을 거치며 모두를 대체하는 javascript 함수를 정의하십시오. [rowindex -1]로 [rowindex]의 인스턴스 –

관련 문제