2012-01-18 4 views
3

MVC3에서 다중 레벨 편집기를 만들려고합니다. 다중 레벨이란 3 가지 계층 구조 (상위 오브젝트, 상위의 하위 오브젝트 및 하위 하위 오브젝트의 콜렉션)에 대한 데이터를 편집 할 수 있음을 의미합니다. 내가 한 화면에 전체 계층 구조를 표시 할 때문에Asp.Net MVC3 면도기 - 편집자가 게시하지 않은 하위 항목 목록

namespace MvcApplication1.Models 
{ 
    public class Parent 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
     public Child Child { get; set; } 
    } 

    public class Child 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
     public IEnumerable<SubChild> SubChildren { get; set; }  
    } 

    public class SubChild 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
     private DateTime _date = DateTime.Now; 
     public DateTime Date { get { return _date; } set { this._date = value; } } 
    } 
} 

내가 다음 뷰 모델 생성 :처럼 내 모델은 약 보이는

namespace MvcApplication1.Models.ViewModels 
{ 
    public class ParentViewModel 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
     public Child Child { get; set; } 
     public IEnumerable<SubChild> SubChildren { get { return Child.SubChildren; } set { this.Child.SubChildren = value; } } 
    } 
} 

및 컨트롤러가 보이는 것처럼 :

public class ParentController : Controller 
    { 
     public ActionResult MultiLevelEdit(int id) 
     { 
      // Simulate data retrieval 
      Parent parent = new Parent { Id = 2 , Name = "P"}; 
      var child = new Child { Id = 3, Name = "Cild1" }; 
      List<SubChild> children = new List<SubChild>(); 
      children.Add(new SubChild { Id = 3, Name = "S1"}); 
      children.Add(new SubChild { Id = 5, Name = "S 22" }); 
      child.SubChildren = children; 
      parent.Child = child; 
      // Create view model 
      ParentViewModel vm = new ParentViewModel() { Id = parent.Id, Name = parent.Name, Child = parent.Child, SubChildren = parent.Child.SubChildren }; 

      return View(vm); 
     } 

    } 

보기가 렌더링됩니다 :

@model MvcApplication1.Models.ViewModels.ParentViewModel 

@using (Html.BeginForm()) { 
    @Html.ValidationSummary(true) 
    <fieldset> 

    @Html.HiddenFor(model => model.Id) 
    @Html.LabelFor(model => model.Name) 
    @Html.EditorFor(model => model.Name) 
    <hr /> 
    Child 
    <br /> 
    @Html.EditorFor(model => model.Child) 

    <hr /> 
    SubChild 
    <br /> 
    @Html.EditorFor(model => model.SubChildren) 


    <p> 
      <input type="submit" value="Save" /> 
     </p> 
    </fieldset> 
} 

내가 공유 \ EditorTemplates \ 뷰에 두 개의 편집기 템플릿을 만들었습니다

ChildTemplate.cshtml

@model MvcApplication1.Models.Child 

@{ 
    ViewBag.Title = "Child"; 
} 

<h2>Child</h2> 

@using (Html.BeginForm()) { 
    @Html.ValidationSummary(true) 
    <fieldset> 
     <legend>Child</legend> 

     @Html.HiddenFor(model => model.Id) 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Name, "Child Name") 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Name) 
      @Html.ValidationMessageFor(model => model.Name) 
     </div> 
    </fieldset> 
} 

및 SubChildTemplate.cshtml을

@model MvcApplication1.Models.SubChild 

@using (Html.BeginForm()) { 
    @Html.ValidationSummary(true) 
    <fieldset> 
     <legend>SubChild</legend> 

     @Html.HiddenFor(model => model.Id) 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Name) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Name) 
      @Html.ValidationMessageFor(model => model.Name) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Date) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Date) 
      @Html.ValidationMessageFor(model => model.Date) 
     </div> 
    </fieldset> 
} 

모든 것은 내가하려고하지만 할 때, 제대로 렌더링 SubChildren 컬렉션이 null 인 변경 내용을 저장합니다. 나는 편집 방법이 명 서명 시도 :

[HttpPost] 
public ActionResult MultiLevelEdit(ParentViewModel parentVM) 
{... 

[HttpPost] 
public ActionResult MultiLevelEdit(ParentViewModel parentVM, FormCollection collection) 
{... 

을 그 어떤에 값이 없습니다.

누구든지 제안 할 수 있습니까? 미리 감사드립니다.

답변

3

템플릿의 이름이 올바르게 지정되지 않았습니다. 해야합니다 ~/Views/Shared/EditorTemplates/SubChild.cshtml

~/Views/Shared/EditorTemplates/Child.cshtml

    • 이 또한 내가 꽤 뷰 모델에 SubChildren 속성의 목적을 볼 수 없습니다.

      당신은 그것을 제거하고 기본보기의 수 :

      @model MvcApplication1.Models.ViewModels.ParentViewModel 
      
      @using (Html.BeginForm()) { 
          @Html.ValidationSummary(true) 
          <fieldset> 
      
          @Html.HiddenFor(model => model.Id) 
          @Html.LabelFor(model => model.Name) 
          @Html.EditorFor(model => model.Name) 
          <hr /> 
          Child 
          <br /> 
          @Html.EditorFor(model => model.Child) 
      
          <hr /> 
          SubChild 
          <br /> 
          @Html.EditorFor(model => model.Child.SubChildren) 
      
          <p> 
           <input type="submit" value="Save" /> 
          </p> 
          </fieldset> 
      } 
      

      을하지만 가장 큰 문제는 HTML을 사용할 수 없습니다 <form> 요소를 내포 한 것입니다. 잘못된 HTML이고 정의되지 않은 동작이 발생합니다. 일부 값은 게시 될 수도 있고 다른 값은 게시되지 않을 수도 있습니다 ... 기본보기에 양식이 이미 포함되어 있기 때문에 Html.BeginForm 도우미를 템플릿에서 제거하십시오.

  • +0

    감사합니다. @ 다린. 그동안 템플릿 이름을 수정했습니다.중첩 된 양식의 정확성을 확신 할 수 없었지만 제안이 없으면 곧 그렇게 제거하지는 않을 것입니다. 이제 모든 것이 올바르게 표시됩니다. 나는 여전히 서버에 다시 게시 할 때 모델에 올바르게 바인딩되지 않은 편집기의 일부 값에 대해 몇 가지 문제를 가지고 있지만 이것이 또 다른 게시물이 될 것입니다. – Konrad

    1

    해결 방법은 this article을 참조하십시오. 마법은 using (Html.BeginCollectionItem ("...")) 블록에 포함되어 있습니다.

    즉, 기본 모델 바인더로 작업 할 때 올바른 필드 이름/접두사를 사용해야합니다.

    +0

    제안 해 주셔서 감사합니다. @Jan. Darin의 제안으로이 문제를 해결했지만 BeginCollectionItem ("...") 도우미에 대해 알아두면 좋습니다. – Konrad