2014-09-26 7 views
8

У меня длинная форма, которую я разбил на несколько частей, и использую @ Html.EditorFor для каждого раздела, который отлично работает, но вам нужны ваши мысли о том, можно ли улучшить этот подход или нет.Передача коллекции в EditorFor в ASP.NET MVC

Есть сегменты, и каждый сегмент может иметь несколько действий, поэтому у меня есть коллекция сегментов, и каждый сегмент в этой коллекции содержит сборник мероприятий.

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; } 
    } 

Это было, как я хотел ViewModel, что я использую в качестве модели для представления должны выглядеть, но не мог заставить его работать, так как @ Html.EditorFor не принимает тип коллекции.

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

Вот ViewModel

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

Вот это EditorFor Шаблон для Сегменты

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

Но это не работает, говоря EditorFor не может принимать коллекции и исключение в RunTime ,

Вот моя работа Вокруг. Я создал другой класс «UglySegmentWorkAround», который содержит коллекцию сегментов, а затем в UserPreferencesViewModel я удалил свойство List и вместо этого определил для этого свойство.

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

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

и вот редактор для шаблона.

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

Он отлично работает, но я просто не чувствую себя комфортно с этим подходом, есть все, что мне не хватает в первом подходе? Как это должно быть сделано? Я не хочу, чтобы EditorFor выполнял неявный цикл, если я передаю ему коллекцию, потому что я представляю сложную структуру пользовательского интерфейса в EditorFor, и мне нужен редактор для того, чтобы иметь внутри него цикл.

+0

Проверьте это [ссылка] (http://stackoverflow.com/questions/13420791/mvc-editorfor-not-working-for-collection) –

+0

@HasanFahim I don Не хочу писать цикл for вне редактора. Как я уже упоминал в моем вопросе, скорее мой пользовательский интерфейс требует, чтобы я зацикливал на коллекции внутри редактора. –

ответ

28

EditorFor предназначен для перебора коллекций для вас. Он делает это автоматически. Когда вы передаете коллекцию в редактор, она автоматически вызовет ваш шаблон для каждого элемента коллекции.

Если вам нужно настроить какой-либо рендеринг для коллекции в целом, вы должны сделать это за пределами редактора для вызова, либо в коде просмотра, либо в частичном представлении, которое вызывает ваш редактор.

Например, если вы хотите поместить свой код в таблице, вы могли бы сделать это (где MyCollection является 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 лучший способ сделать это - использовать малоизвестную и плохо документированную «функцию» шаблонов редактора. И эта «особенность» заключается в том, что если вы укажете имя шаблона в качестве аргумента, он не будет перебирать коллекцию. Вы можете использовать эту форму, чтобы «обернуть» ваши шаблоны элементов коллекции.

/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> 

ПРИМЕЧАНИЕ: Я говорю «особенность», потому что здесь возникло много вопросов о том, что это не повторение сборов если имя шаблона явно указано в аргументах)

+4

«И эта« особенность »заключается в том, что если вы укажете имя шаблона в качестве аргумента, то оно не перебирает коллекцию« Большое спасибо за это. – Jono

+0

Необходимо было поместить шаблоны в папку/Views/Shared/EditorTemplates, чтобы я мог заставить ее работать –

+0

@LarsLadegaard - Ты прав, не уверен, как я ошибся. Я исправлю это в сообщении. Я должен отметить, что EditorTemplates следует использовать только в Shared, если они действительно разделены, их следует поместить в папку «Представления контроллеров», если они нужны только одному контроллеру. –

Смежные вопросы