2013-11-26 2 views
0

Я хочу отобразить статью с несколькими полями в моем представлении, но она не работает правильно: поля не отображаются (только заголовок (имена полей)).Невозможно отобразить шаблон редактора для вложенного IEnumerable

класс

Статья:

public class Article : IComparable 
{ 
    public IEnumerable<ArticleField> Fields 
    { 
     get; 
     set; 
    } 

    [More properties...] 
} 

ArticleField класс:

public class ArticleField 
{ 
    // !! I want this display in a table Header !! 
    [Display(Name = "Name", ResourceType = typeof(Resources.Classes.ArticleField))] 
    [Required(ErrorMessageResourceName="required", ErrorMessageResourceType=typeof(Resources.Common.Validation))] 
    public string Name 
    { 
     get; 
     set; 
    } 
    [More properties...] 
} 

Index.cshtml (появляются штраф оказанной HTML)

@model MygLogWeb.Classes.Article.Article 

@using (Html.BeginForm("Index", "Article", FormMethod.Post)) 
{ 
    @Html.AntiForgeryToken() 

    <table class="table"> 
     <tbody> 

      <tr> 
       <th> 
        @Html.DisplayNameFor(model => model.Name) 
       </th> 
       <td> 
        @if (Model.IsSystem) 
        { 
         @Html.HiddenFor(model => model.Name) 
         @Model.Name 
        } 
        else 
        { 
         @Html.EditorFor(model => model.Name) 
        } 
       </td> 
      </tr> 
      <tr> 
       <th> 
        @Html.DisplayNameFor(model => model.IsSystem) 
       </th> 
       <td> 
        @Html.HiddenFor(model => model.IsSystem) 
        @Model.IsSystem 
       </td> 
      </tr> 
     </tbody> 
    </table> 

    <br style="margin: 0.5em 0em;"/> 

    @* POINT OF INTEREST *@ 
    @Html.EditorFor(model => model.Fields, "ArticleFields") 

    <button type="submit" name="button" value="save">@Resources.Common.Buttons.save</button> 
} 

EditorTemplates/ArticleFields.cshtml (появляются штраф rendered html)

@model IEnumerable<MygLogWeb.Classes.Article.ArticleField> 

@using MygLogWeb.Classes.Article 

@{ 
    var uid = Guid.NewGuid().ToString(); 
    var GlobalViewBag = ViewContext.Controller.ViewBag; 

    GlobalViewBag.ItemCount = Model.Count(); 
} 

<table class="table none" id="@uid"> 
    <thead> 
     <tr> 
      <th> 
       @Html.DisplayNameFor(model => model.IsSystem) 
      </th> 
      <th> 
       @Html.DisplayNameFor(model => model.IsVirtual) 
      </th> 
      <th> 
       @Html.DisplayNameFor(model => model.Name) 
      </th> 
      <th> 
       @Html.DisplayNameFor(model => model.Formula) 
      </th> 
      <th></th> 
     </tr> 
    </thead> 
    <tbody> 
     <tr> 
      <td> 
       @* POINT OF INTEREST *@ 
       @Html.EditorFor(model => model) 
      </td> 
     </tr> 
    </tbody> 
    <tfoot> 
     <tr> 
      <td colspan="5"> 
       <input type="button" value="@Resources.Common.Buttons.add" data-row-add="ArticleField" data-row-addto="#@uid > TBODY" /> 
      </td> 
     </tr> 
    </tfoot> 
</table> 

<script type="text/javascript"> 
    new TableEdit("@uid"); 
</script> 

EditorTemplates/ArticleFields.cshtml (не появляется вообще оказанной HTML)

@model MygLogWeb.Classes.Article.ArticleField 

xxx 

я, хотя я мог бы сделать public IEnumerable<ArticleField> Fields с List<T>, но тогда я получаю вопрос с заголовками. Код, такой как @Html.DisplayNameFor(model => model.Formula), не работает.

+0

Что-то не подходит для меня. В вашем шаблоне 'EditorTemplates/ArticleFields.cshtml' вы объявляете свою модель как« IEnumerable », но никогда не повторяете ее. Почему так? –

+0

Насколько я знаю, я не могу повторять. Оператор [] не существует в IEnumerable и требуется для правильно названных полей. Поэтому я должен позволить MVC обрабатывать IEnumerable, как обычно, это нормально, когда ваша основная (Index.cshtml) модель является IEnumerable. – Serge

+0

Используйте 'ToList()' then. –

ответ

1

Вместо

@Html.EditorFor(model => model) 

Вы должны использовать элемент коллекции

@Html.EditorFor(model => model[0]) 

или цикл над элементами

@foreach (var item in Model) 
{ 
    @Html.EditorFor(model => item) 
} 

Если вы планируете пост обратно с той же модели, тогда вы захотите использовать List, а не IEnumerable для того, чтобы модели по умолчанию связующего в создавать объекты в посте

+0

1) Нет такого оператора для IEnumerable. 2) Мне нужно правильно проиндексированное имя поля forach, что бы сломать это. – Serge

+0

Я упомянул проблему заголовка, используя List. Если у вас есть хороший обходной путь, это поможет мне решить проблему. – Serge

+0

http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx – Kaido

0

Преобразование модели в список, итерацию и использовать Editor вместо EditorFor. Что-то вдоль этой линии:

foreach(var entry in Model.ToList()) 
{ 
    Editor(entry, "ArticleFieldsItem"); 
} 

А затем создать еще один шаблон:

@model MygLogWeb.Classes.Article.ArticleField 

<td>@Html.DisplayFor(model => model.IsSystem)</td> 
<td>@Html.DisplayFor(model => model.IsVirtual)</td> 
<td>@Html.DisplayFor(model => model.Name)</td> 
<td>@Html.DisplayFor(model => model.Formula)</td> 
+0

Я бы полностью сломал имена полей. – Serge

+0

В настоящее время вы пытаетесь создать шаблон, который автоматически отображает иерархические данные. Это не совсем так. Однако вы можете разбить уровни. Имейте шаблон для одного объекта «ArticleField» и другого для всего объекта «Поля». См. Мое редактирование. –

0

В конце концов я сделал то, что я не хотел, я полностью прекращалось IEnumerable свойства в моей модели и использовать массивы или списки вместо.

Тогда я, конечно, мог бы использовать для циклов (не foreach) с [index].

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