2009-07-08 6 views
1

MVC 웹 응용 프로그램에서 작업 중이며 가변 길이 항목 목록이 있어야합니다. 사용자는 모든 행에 대해 배치 업데이트를 수행하는 저장으로 행을 추가/편집 및 삭제할 수 있어야합니다.MVC에서 항목의 가변 길이 목록 편집

나는 대부분의 작업을 거의 다 다루었 기 때문에 Steve Sanderson에게 모든 신용을 부여한 두 개의 블로그 게시물에서 일하기 시작했습니다.

<% using (Html.BeginForm()) { %> 

<div id="placeholder"> 
    <% for (int i = 0; i < Model.Count(); i++) 
     { 
      ViewData["index"] = i; 
      Html.RenderPartial("ProfileItemLine", Model.ElementAt(i), new ViewDataDictionary(ViewData) { 
      {"prefix", "items"} 
     }); 
     } 
    %> 
</div> 

<div id="addProfileItem"> 
    <a href="" id="addItem">Add another item</a> 
</div> 

<input type="submit" value="Save changes" /> 

<% } %> 

을 다음과 추가 사항을 처리하기 위해 jQuery를 사용하여 삭제로

Editing a variable-length list of items in ASP.NET MVC

나는 내 시야를 가지고

$(document).ready(function() { 

    var nextIndex = <%=ViewData.Model.Count()%>; 
    setRemoveLinks(); 

    $('#addItem').click(function() { 
     var action = '/Profile/BlankItemLine?index=' + nextIndex; 
     $.get(action, 'html', function(lineItemHtml) { 
      $('#placeholder').append(lineItemHtml); 
      setRemoveLinks(); 
     }); 
     nextIndex++; 
     return false; 
    }); 
}); 

function setRemoveLinks() { 
    $('a.removeItem').click(function() { 
     $(this).parent('div').remove(); 
     return false; 
    }); 
} 

마이너스 서식 및 일반 텍스트

을 다음과 같이 ProfileItemLine ViewUserControl입니다
<div> 
<% var fieldPrefix = string.Format("{0}[{1}].", ViewData["prefix"], ViewData.Model.Sequence); %> 
<%= Html.Hidden(fieldPrefix + "ProfileItemId", ViewData.Model.ProfileItemId)%> 
<%= Html.TextBox(fieldPrefix + "Title", ViewData.Model.Title, new { size = "30"})%> 
<%= Html.CheckBox(fieldPrefix + "IsHighlighted", ViewData.Model.IsHighlighted)%> 
<a href="" class="removeItem">Delete</a></div> 

지금까지는 목록이 모델에 올바르게 바인딩되어 있고 항목을 추가하는 한 제대로 작동합니다.

문제는 삭제와 관련이 있습니다. 삭제가 작동하고 올바른 행이 제거되지만 양식 제출시 모든 바인딩이 손실됩니다. Steve의 포스트에서 RC는 모델 바인딩이 작동하는 방식을 변경했으며 모든 인덱스가 깨지지 않은 오름차순 시퀀스에 있어야한다고 언급했습니다.

스티브는 양식 제출시 목록을 재정렬하는 작업을 수행하기 위해 일부 코드를 나열했지만 지원되지 않는 메서드를 사용하여 "var controls ="행에 예외를 발생시킵니다. 양식를 IEnumerable 인덱스 1이 삭제 2

<div id="placeholder"> 
<div> 
    <input id="items[0]_ProfileItemId" name="items[0].ProfileItemId" type="hidden" value="0fd3a3f5-907e-4eb1-8f69-26e3840e5e12" /> 
    <input id="items[0]_Title" name="items[0].Title" size="30" type="text" value="Number 1" /> 
    <input id="items[0]_IsHighlighted" name="items[0].IsHighlighted" type="checkbox" value="true" /> 
    <input name="items[0].IsHighlighted" type="hidden" value="false" /> 
    <a href="" class="removeItem">Delete</a> 
</div> 
<div> 
    <input id="items[3]_ProfileItemId" name="items[3].ProfileItemId" type="hidden" value="0fa1a3f5-907e-4eb1-8f69-26e3840e5e12" /> 
    <input id="items[3]_Title" name="items[3].Title" size="30" type="text" value="Number 3" /> 
    <input id="items[3]_IsHighlighted" name="items[3].IsHighlighted" type="checkbox" value="true" /> 
    <input name="items[3].IsHighlighted" type="hidden" value="false" /> 
    <a href="" class="removeItem">Delete</a> 
</div> 
</div> 

I 모델 바인딩 후 HTML 출력의

$(function() { 
$("form").submit(function() { 
    // Normalize the sequence before submitting the form 
    ensureControlGroupsInNumericalOrder("#placeholder div", "items"); 
});}); 

function ensureControlGroupsInNumericalOrder(groupSelector, controlNamePrefix) { 
var groups = $(groupSelector); 
var nameToEndOfIndexRegex = new RegExp(controlNamePrefix + "\\[\\d+"); 
for (var seq = 0; seq < groups.length; seq++) { 
    var controls = $("*[name~=" + controlNamePrefix + "\[]", groups[seq]); 
    for (var c = 0; c < controls.length; c++) 
     controls[c].name = controls[c].name.replace(nameToEndOfIndexRegex, controlNamePrefix + "[" + seq); 
}} 

예, 제출이 예에서 난 단지 다시 아닌 첫 번째 항목을 얻을 것 두 번째 항목은 1이 아닌 items [3]입니다. 사람이 솔루션 날 지점 수 있는지 궁금 있도록

public ActionResult EditItems(Guid id, IEnumerable<ProfileItem> items) 
{ 
    if (ModelState.IsValid) 
    { 
     // Save items 
    } 
    if (ModelState.IsValid) 
     return RedirectToAction("Index"); 
    else 
     return View(items); 
} 

는 여전히 jQuery를 정규 표현식에 내 이빨을 절단하고있다.

미리 감사드립니다.

답변

1

왜 개별 요소 정보가 필요합니까? 삭제를 들어

<div id="div1"> 

를 사용하는

그것은 현명하지 않을까요?

<a rel="1" id="item + item id (not per se 1)" class="delete">delete</a> 

그래서 당신은 내가 항상 :) 무엇 있다는

$('.delete').bind('click',function(){ 
    $('#div' + $(this).attr('rel')).remove(); 
    // plus delete call to db ? 
}); 

을 사용할 수 있습니다

당신은 당신의 HTML을 생성 루프에서 만든 사업부와 REL의 수, 그래서 순서를 가질 수있다 항상 정확합니다.

+0

안녕하세요, 내 시나리오에서 작동합니까? 나는 개별 요소 정보가 모델 바인딩과 관련이 있다고 생각한다. 참조 http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx 내 요구 사항은 일괄 작업으로 db에 대한 개별 호출이 발생할 수 없다는 것입니다. 그래서 아직 귀하의 솔루션을 시도했지만 나는 이것이 대답인지 확신하지 못합니다. 실천 사례가 있습니까? –