2012-02-03 25 views
21

Tôi đã bị kẹt một thời gian dài để chỉnh sửa một phần con của mô hình của tôi, bộ sưu tập của mô hình đã đến null.Asp: net MVC 3: @ Html.EditorFor một subcollection của mô hình của tôi trong một mẫu?

cuối cùng tôi đã tìm thấy một giải pháp, nhưng tôi thấy nó một chút bẩn:

Đầu tiên thử nghiệm của tôi dữ liệu ngay:

đối tượng Mẫu:

public class ContainerObject 
    { 
     public String Title { get; set; } 
     public List<ContainedObject> ObjectList { get; set; } 
    } 

Sub đối tượng bộ sưu tập:

public class ContainedObject 
{ 
    public int Id { get; set; } 
    public String Text { get; set; } 
    public Boolean IsSelected { get; set; } 
} 

điều khiển phương pháp mà tạo ra các đối tượng

public ActionResult TestForm() 
    { 
     return View(new ContainerObject() 
     { 
      Title = "This is a sample title", 
      ObjectList = new List<ContainedObject>() 
       { 
        new ContainedObject(){Id=1, IsSelected = true, Text="ObjectOne"}, 
        new ContainedObject(){Id=2, IsSelected = false, Text="ObjectTwo"}, 
        new ContainedObject(){Id=3, IsSelected = true, Text="ObjectThree"}, 
        new ContainedObject(){Id=4, IsSelected = false, Text="ObjectFour"}, 
       } 
     }); 
    } 

điều khiển mà nhận đối tượng sửa

[HttpPost] 
    public ActionResult TestFormResult(ContainerObject filledObject) 
    { 
     return View(); 
    } 

Quan điểm

@model WebTestApplication.Models.ContainerObject 

@{ 
    ViewBag.Title = "TestForm"; 
} 
@using (Html.BeginForm("TestFormResult","Home", FormMethod.Post)){ 
    @Html.EditorFor(x => x.Title) 
    Html.RenderPartial("ContainedObject", Model.ObjectList); 
    <input type="submit" value="Submit"/> 
} 

Các phần v iew (ContainedObject.cshtml)

@model IEnumerable<WebTestApplication.Models.ContainedObject> 
@{ 
    ViewBag.Title = "ContainedObject"; 
    int i = 0; 
} 
@foreach (WebTestApplication.Models.ContainedObject currentObject in Model) 
{ 
    <br /> 
    @Html.Label(currentObject.Text); 
    @Html.CheckBox("ObjectList[" + i + "].IsSelected", currentObject.IsSelected);                          
    @Html.Hidden("ObjectList[" + i + "].Id", currentObject.Id);                         
    @Html.Hidden("ObjectList[" + i + "].Text", currentObject.Text); 
    i++; 
} 

này được thực sự làm việc, nhưng tôi đã có một vấn đề:

  • Tôi đã tạo ra tên mình và xác định tài sản của đối tượng chứa

Tôi cố gắng sử dụng Html.EditorFor thay vì Html.RenderPartial trong chế độ xem, sự cố là nó tạo cho tôi tên "ObjectList. [0] .Id" (có thêm. giữa tên thuộc tính và người truy cập).

Tôi cũng đã cố gắng chỉ sử dụng @ Html.EditorFor ở chế độ xem một phần, nhưng nó tạo ra các vars với tên của đối tượng.

Nếu tôi không sử dụng bất kỳ mẫu nào, nó hoạt động:

@model WebTestApplication.Models.ContainerObject 

@{ 
    ViewBag.Title = "TestForm"; 
} 
@using (Html.BeginForm("TestFormResult", "Home", FormMethod.Post)) 
{ 
    @Html.EditorFor(x => x.Title) 
    for (int i = 0; i < Model.ObjectList.Count; i++) 
    { 
     <br /> 
     @Html.Label(Model.ObjectList[i].Text); 
     @Html.CheckBoxFor(m => Model.ObjectList[i].IsSelected); 
     @Html.HiddenFor(m => Model.ObjectList[i].Id); 
     @Html.HiddenFor(m => Model.ObjectList[i].Text); 
    } 

    <br /><input type="submit" value="Submit"/> 
} 

Nhưng ở đây đó là một mẫu đơn giản, nhưng trong trường hợp thật của tôi, tôi sẽ có nhiều dữ liệu hơn, và điều này sẽ được tái sử dụng nhiều lần. Vì vậy, lựa chọn tốt nhất của tôi là gì?

Trả lời

38

Bạn có thể đơn giản hóa mã của mình bằng cách giới thiệu EditorTemplate. Sau đây là cách:

  • Quan điểm chính vẫn là khá nhiều giống ngoại trừ chúng tôi thay thế renderPartial với EditorFor:

TestForm.cshtml

@model WebTestApplication.Models.ContainerObject 

@{ 
    ViewBag.Title = "TestForm"; 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 

@using (Html.BeginForm("TestFormResult", "Home", FormMethod.Post)) { 
    @Html.EditorFor(m => m.Title) 
    @Html.EditorFor(m => m.ObjectList); 

    <input type="submit" value="Submit" /> 
} 
  • Sau đó tạo một thư mục có tên EditorTemplates dưới Views/Home (giả sử điều khiển của bạn là Home):

enter image description here

  • và thêm dòng sau mẫu cho ContainedObj vv:

ContainedObject.cshtml

@model WebTestApplication.Models.ContainedObject 

<p> 
    @Html.DisplayFor(m => m.Text) 
    @Html.CheckBoxFor(m => m.IsSelected) 
    @Html.HiddenFor(m => m.Id) 
    @Html.HiddenFor(m => m.Text) 
</p> 

Biên tập viên sẽ tự động lặp qua danh sách các đối tượng render quan điểm cho mỗi trong số họ. Hy vọng nó giúp.

+1

tuyệt vời! Tôi không biết rằng trình soạn thảoCho hoặc DisplayFor sẽ tự động lặp lại nếu đó là danh sách! Có cách nào để làm cho nó hoạt động khi chỉ định mẫu nó phải sử dụng? – J4N

+0

Bởi vì trong thực tế tôi đã nhiều lần một số thông tin có thể được hiển thị với hộp kiểm (nhiều lựa chọn) hoặc với nút radio (chọn một mục), trong cùng một bộ điều khiển (ví dụ như giá trị đã chọn và giá trị mặc định) – J4N

+0

Bạn muốn chỉ định các mẫu khác nhau? Nếu vậy, có quá tải cho EditorFor chấp nhận tên mẫu. –

5

Tôi đã tìm thấy chuỗi này trong khi tìm kiếm thứ gì đó khác có liên quan. Denis có câu trả lời đúng, nhưng tôi nghĩ tôi sẽ thêm một số cú pháp trong trường hợp bất kỳ ai khác bắt gặp điều này:

Nếu bạn có mẫu trình chỉnh sửa có tên "SomeTemplate.cshtml", bạn có thể sử dụng nó cho danh sách Mục như sau xem của bạn:

@for (var i = 0; i < Model.ObjectList.Count(); i++) 
{ 
    @Html.EditorFor(m => m.ObjectList[i], "SomeTemplate") 
} 

Sau đó, trong mẫu soạn thảo của bạn:

@model WebTestApplication.Models.ContainedObject 

<br /> 
@Html.Label(Model.Text); 
@Html.CheckBoxFor(m => m.IsSelected); 
@Html.HiddenFor(m => m.Id); 
@Html.HiddenFor(m => m.Text); 
Các vấn đề liên quan