Проблема с MVC EditorFor named template
У меня есть то, что появляется (для меня все равно), чтобы быть странной проблемой...
Я создал простой шаблон редактора для 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
Я не понимаю, почему работает шаблон по умолчанию, а именованный шаблон - нет. Любая помощь будет оценена.
Спасибо.
Ответы
Ответ 1
Когда вы вызываете @Html.EditorFor(c => c.Categories)
, он возвращается к шаблону по умолчанию для IEnumerable. Этот шаблон по умолчанию предоставляется структурой MVC, и его поведение заключается в выводе Html.EditorFor()
для каждого элемента в перечислении. Это, в свою очередь, испускает подходящий шаблон редактора для каждого элемента в списке индивидуально - в вашем случае все экземпляры SelectListItem
, поэтому в первом случае для каждого элемента используется шаблон SelectListItem
.
Во втором случае, явно указав, что ваш EditorFor
использует конкретный шаблон редактора CategoryIcons
, вы говорите ему, чтобы использовать этот шаблон редактора для всей перечисления, вместо того, чтобы по умолчанию использовать шаблонный шаблон, в свою очередь, используя шаблон для каждого перечисляемого элемента.
Я еще не уверен в этом.
Один из подходов заключался бы в определении шаблона CategoryIcons
, модель которого представляет собой экземпляр IEnumerable<CategoryIcon>
, который просто запрашивает перечисление Model
и выполняет Html.EditorFor
для каждого элемента с явной ссылкой на шаблон CategoryIcon
. Затем вы помещаете шаблон шаблона для каждого элемента в этот шаблон (CategoryIcon
not CategoryIcons
). Тогда вы вызовете это, выполнив @Html.EditorFor(c => c.Categories, "CategoryIcons")
.
Я собираюсь посмотреть, есть ли лучшие способы сделать это, но я надеюсь, что это может быть полезно сейчас. Было бы здорово, если бы шаблоны могли быть параметризованы, поэтому вы могли бы написать шаблон IEnumerable, который принимает в качестве аргумента имя шаблона для каждого из своих элементов.
Ответ 2
Просто обновление, я наткнулся на этот вопрос, пытаясь решить ту же проблему самостоятельно.
То, что я закончил, - это повторение каждого экземпляра коллекции и вызов 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>
По-прежнему не чист, но мне это нравится лучше, чем наследование нового класса, как вы делали.
(Извините, если мой синтаксис С# немного выключен, я пишу в vb.net)
Ответ 3
Если вы используете EditorFor, я не думаю, что решение цикла будет работать. Похоже, что использование шаблона IEnumerable является единственным способом правильного имени входов формы; если вы просто назовете EditorFor несколько раз, то ваша форма <INPUT>
будет иметь тот же идентификатор, а не индексированные идентификаторы.
У меня возникла эта проблема, а решение должно было испускать перечислимый шаблон и цикл не через элементы списка.
Извините, что этот ответ не является комментарием - не имеют комментариев.