2014-09-26 12 views
8

Tôi có một biểu mẫu dài mà tôi đã chia nhỏ thành nhiều phần và đang sử dụng @ Html.EditorFor cho từng phần đang hoạt động tuyệt vời nhưng cần suy nghĩ của bạn về cách tiếp cận này có thể cải thiện hay không.Chuyển Bộ sưu tập tới EditorFor trong ASP.NET MVC

Có phân đoạn và mỗi phân đoạn có thể có nhiều hoạt động, vì vậy tôi có một bộ sưu tập phân đoạn và mọi phân đoạn trong bộ sưu tập này chứa một bộ sưu tập các hoạt động.

public class Activity 
    { 
     public string ActivityId { get; set; } 
     public string ActivityDescription { get; set; } 
     public bool IsSelected { get; set; } 
    } 
    public class Segment 
    { 
     public string SegmentId { get; set; } 
     public string SegmentDescription { get; set; } 
     public List<Activity> Activitites { get; set; } 
    } 

Đây là cách tôi muốn ViewModel mà tôi sử dụng như một mô hình cho quan điểm nên trông giống như nhưng không thể làm cho nó làm việc kể từ khi @ Html.EditorFor không chấp nhận một loại Collection.

public class UserPreferencesViewModel 
    { 
     //..... Other Properties 
     public List<Segment> Segments {get; set;} 
    } 

Đây là ViewModel

@model UserPreferencesViewModel 
@{ 
    //... Other Properties 
    @Html.EditorFor(m => m.Segments) //I assigned Segments three Segments in the Controller Get Method 
} 

Dưới đây là mẫu EditorFor cho Segments

@model List<Segment> 
@{ 
    //... Other Properties 
    @foreach(var segment in Model) 
    { 
     //Do the stuff 
    } 
} 

Nhưng điều này không làm việc nói EditorFor không thể lấy bộ sưu tập và các ngoại lệ được ném vào RunTime .

Đây là công việc của tôi Xung quanh. Tôi tạo ra một lớp "UglySegmentWorkAround" có chứa các bộ sưu tập phân đoạn và sau đó trong UserPreferencesViewModel tôi loại bỏ các tài sản danh sách và thay vào đó được xác định một tài sản cho điều đó.

public class UglySegmentWorkAround 
{ 
public List<Segment> Segments {get; set;} 
} 

public class UserPreferencesViewModel 
     { 
      //..... Other Properties 
      public UglySegmentWorkAround UglySegmentWorkAround {get; set;} 
     } 

và đây là mẫu EditorFor.

@model UglySegmentWorkAround 
    @{ 
     //... Other Properties 
     @foreach(var segments in Model.Segments) 
     { 
      //Do the stuff 
     } 
    } 

Nó hoạt động hoàn hảo nhưng tôi không cảm thấy thoải mái với cách tiếp cận này, có điều gì tôi thiếu trong cách tiếp cận đầu tiên không? Làm thế nào điều này nên được thực hiện? Tôi không muốn EditorFor làm một vòng lặp ngầm nếu tôi chuyển cho nó một bộ sưu tập vì tôi đang vẽ một cấu trúc giao diện người dùng phức tạp trong EditorFor và tôi cần EditorFor để có vòng lặp bên trong nó.

+0

Kiểm tra [link] này (http://stackoverflow.com/questions/13420791/mvc-editorfor-not-working-for-collection) –

+0

@HasanFahim I don không muốn viết một vòng lặp for bên ngoài EditorFor như tôi đã đề cập trong câu hỏi của tôi, thay vì giao diện người dùng của tôi yêu cầu tôi lặp lại các bộ sưu tập bên trong Trình soạn thảo. –

Trả lời

28

EditorFor được thiết kế để lặp qua bộ sưu tập cho bạn. Nó thực hiện điều này tự động. Khi bạn chuyển một bộ sưu tập vào một EditorFor, nó sẽ tự động gọi mẫu của bạn cho mỗi mục trong bộ sưu tập.

Nếu bạn cần thiết lập một số hiển thị cho toàn bộ bộ sưu tập thì bạn nên thực hiện việc này bên ngoài cuộc gọi EditorFor, trong mã chế độ xem của bạn hoặc trong chế độ xem một phần gọi EditorFor của bạn.

Ví dụ, nếu bạn muốn đưa code của bạn trong một bảng, bạn sẽ làm điều này (nơi MyCollection là List<MyItem>):

_MyCollectionPartial.cshtml

<table> 
    <tr> 
     <th>Foo...</th> 
     ... 
    <tr> 
    @Html.EditorFor(x => x.MyCollection) 
</table> 

/Views/Shared/EditorTemplates/MyItem.cshtml

@model MyItem 
<tr> 
    <td>@Html.TextBox(x => x.Foo)</td> 
    .... 
</tr> 

EDIT:

Perhap Một cách tốt hơn để làm điều này là sử dụng một ít tính năng "được biết đến" và ít được ghi lại trong các mẫu của Trình chỉnh sửa. Và "tính năng" đó là nếu bạn chỉ định một tên mẫu làm đối số, thì nó không lặp qua bộ sưu tập. Bạn có thể sử dụng biểu mẫu này để "bọc" các mẫu mục bộ sưu tập của bạn.

/Home/Index.cshtml

.... your html 
@Html.EditorFor(model => model.MyCollection, "MyCollectionLayout") 

/Views/Shared/EditorTemplates/MyCollectionLayout.cshtml

@model List<MyItem> 
<table> 
    <tr> 
     <th>Foo...</th> 
     ... 
    <tr> 
    @Html.EditorForModel() (Or alternatively @Html.EditorFor(model => model) 
</table> 

/Views/Shared/EditorTemplates/MyItem.cshtml

@model MyItem 
<tr> 
    <td>@Html.TextBoxFor(x => x.Foo)</td> 
    .... 
</tr> 

LƯU Ý: Tôi nói "tính năng" vì điều này đã tạo ra nhiều câu hỏi ở đây về SO về nó không lặp qua thu thập các ion khi tên mẫu được chỉ định rõ ràng trong các đối số)

+4

"Và" tính năng "đó là nếu bạn chỉ định tên mẫu làm đối số, thì nó sẽ không lặp lại trong bộ sưu tập" Rất cám ơn vì điều này. – Jono

+0

Nó là cần thiết để đưa mẫu vào thư mục/Views/Shared/EditorTemplates befor tôi có thể làm cho nó hoạt động –

+0

@LarsLadegaard - Bạn nói đúng, không chắc chắn làm thế nào tôi gõ nhầm điều đó. Tôi sẽ sửa nó trong bài viết. Tôi nên lưu ý rằng EditorTemplates chỉ nên đi trong chia sẻ nếu chúng thực sự được chia sẻ, chúng nên được đặt trong thư mục Controllers Views của bạn nếu chúng chỉ cần thiết trong một bộ điều khiển. –

Các vấn đề liên quan