Проблема с MVC Editor для именованного шаблона - PullRequest
20 голосов
/ 28 апреля 2011

У меня есть, как мне кажется, странная проблема ...

Я создал простой шаблон редактора для SelectListItem (SelectListItem.cshtml в папке ~ / Views / Shared / EditorTemplates)Например:

<ul class="select-list-item cell-15 col-3 omega clearfix">
    @Html.EditorFor(c => c.Categories)
</ul>

Где c.Categories является IEnumerable

Это работало нормально, но я хотел, чтобы другой шаблон отображал коллекцию с немного другой разметкой, поэтому я скопировал и переименовалшаблон редактора, например, для 'CategoryIcons.cshtm' и вызывается следующим образом:

<ul class="select-list-item cell-15 col-3 omega clearfix">
    @Html.EditorFor(c => c.Categories, "CategoryIcons")
</ul>

Короче говоря, единственное отличие состоит в том, что я указываю именованный шаблон редактора.

Когда яоткройте страницу, теперь я получаю следующую ошибку:

Элемент модели, переданный в словарь, имеет тип 'System.Collections.Generic.List`1 [System.Web.Mvc.SelectListItem]', но для этого словаря требуется элемент модели типа 'System.Web.Mvc.SelectListItem'

Объявление модели шаблона в обоих шаблонах id:

@model System.Web.Mvc.SelectListItem

Я не знаюне понимаю, почемуШаблон efault работает, а указанный шаблон - нет.Любая помощь будет оценена.

Спасибо.

Ответы [ 3 ]

29 голосов
/ 28 апреля 2011

Когда вы звоните @Html.EditorFor(c => c.Categories), он возвращается к стандартному шаблону для IEnumerable.Этот шаблон по умолчанию предоставляется платформой MVC, и его поведение заключается в выводе Html.EditorFor() для каждого элемента в перечислении.Это, в свою очередь, генерирует соответствующий шаблон редактора для каждого элемента в списке индивидуально - в вашем случае все они являются экземплярами SelectListItem, поэтому в первом случае шаблон SelectListItem используется для каждого элемента.

Во втором случае, явно указав EditorFor на использование определенного шаблона редактора CategoryIcons, вы говорите ему использовать этот шаблон редактора для всего перечисления вместо того, чтобы перечислятьбыть шаблонным по умолчанию, в свою очередь, используя шаблон для каждого перечисляемого элемента.

Я пока не уверен в лучшем способе обойти это.

Один из подходов заключается в определении CategoryIcons template, модель которого является экземпляром IEnumerable<CategoryIcon>, который просто содержит перечисление Model и выполняет Html.EditorFor для каждого элемента с явной ссылкой на шаблон CategoryIcon.Затем вы помещаете свой редактор для каждого элемента в этот шаблон (CategoryIcon, а не CategoryIcons).Затем вы бы назвали это, выполнив @Html.EditorFor(c => c.Categories, "CategoryIcons").

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

5 голосов
/ 11 августа 2011

Просто обновление, я наткнулся на этот вопрос, пытаясь решить ту же проблему самостоятельно.

В итоге я перебрал каждый экземпляр коллекции и вызвал EdtorFor по отдельности, примерно так:

<ul class="select-list-item cell-15 col-3 omega clearfix">
    @for (int i=0;i<Model.Categories.Count;i++) {
        @Html.EditorFor(c => c.Categories[i], "CategoryIcons")
    }
</ul>

Все еще не чисто, но мне нравится это лучше, чем наследование нового класса, как вы это сделали.

(Извините, если мой синтаксис C # немного отключен, я пишу в vb.net)

1 голос
/ 31 августа 2011

Если вы используете EditorFor, я не думаю, что циклическое решение будет работать.Кажется, что использование шаблона IEnumerable является единственным способом для правильного именования входов формы;если вы будете просто вызывать EditorFor несколько раз, то ваша форма <INPUT> s будет иметь тот же идентификатор, а не индексированные идентификаторы.

Я столкнулся с этой проблемой, и решение состояло в том, чтобы выдать перечислимый шаблон и не перебирать элементы списка.

Извините, что сделал это ответом, а не комментарием - не имею права комментировать.

...