Ответ 1
TL; DR > Именованные шаблоны не работают с коллекциями, используйте цикл foreach, чтобы обойти его. Ниже приведены подробные сведения о том, почему и пример.
Ты сказал:
Любая идея, почему редактор EditorFor не использует шаблон "OrderList" я указанном в аргументе "templateName"? В противном случае, что это аргумент для?
EditorFor
фактически использует шаблон OrderList
, который вы указали, - но вы наткнулись на что-то очень запутанное. В некоторых исследованиях появилось много намеков, но я нашел настоящие гайки и болты в этом сообщении: Проблема с MVC EditorFor именованным шаблоном
Короче говоря, происходит то, что работает по умолчанию: @Html.EditorFor(Model=>Model.Orders)
фактически вызывает шаблон MVC по умолчанию по соглашению, но это совсем не очевидно.
Подумайте об этом так:
В рабочей версии вы передаете тип List<Order>
со ссылкой на Model.Orders
(MANY orders), но шаблон указан с помощью модели Order
(single, NOT MANY).
Интересно. Почему это работает? На первый взгляд кажется, что он должен не работать. Но это работает из-за того, что происходит за кулисами.
Перефразируемый из вышеупомянутого поста:
Когда вы используете
@Html.EditorFor(c => c.Orders)
, выбирается соглашение MVC шаблон по умолчанию дляIEnumerable
. Этот шаблон является частью структуры MVC, и то, что он делает, генерируетHtml.EditorFor()
для каждый элемент в перечислении. Затем этот шаблон генерирует соответствующий шаблон редактора для каждого элемента в списке отдельно- в вашем случае все экземплярыOrder
, поэтому для каждого элемента используется шаблонOrder
.
Это волшебство, и это удобно, но поскольку это происходит по соглашению и в основном скрыто от нас, это источник беспорядка, на мой взгляд.
Теперь, когда вы пытаетесь сделать то же самое, но с использованием именованного шаблона, явно установив свой EditorFor
для использования конкретного шаблона редактора OrderList
, вы получите тот шаблон редактора, который проходит всю нумерацию, - и это является источником ошибки, которую вы опубликовали.
Другими словами, недостающему случаю удается пропустить "магическую" часть рабочего процесса и что именно поэтому он терпит неудачу. Но, семантически это выглядит хорошо и здорово, не так ли? Там путаница.
Рабочий регистр:
your call default MVC template your template
@Html.EditorFor( Model => Model.Orders) IEnumerable template Order template
Неудачный случай:
your call your template
@Html.EditorFor(Model=>Model.Orders, "OrderList") OrderList template ERROR!!!
Существует несколько способов устранения ошибки, но многие из них проблематичны, поскольку они вызывают отображение элементов управления HTML таким образом, чтобы вы не могли обращаться к отдельным элементам управления по индексу POST. Uhhg. (Примечание: рабочий процесс действительно корректно отображает HTML)
Чтобы получить правильные представления HTML-элементов, кажется, что вы должны использовать обычный цикл for
(а не foreach
) и передавать каждый из отдельных объектов Order
в пользовательский шаблон (который я назвал OrderEditorTemplateDefault
).
@for (int i = 0; i < Model.Orders.Count ; i++)
{
@Html.EditorFor(c => Model.Orders[i], "OrderEditorTemplateDefault")
}
Часть вашего вопроса указана:
Я надеялся, что могу использовать разные дочерние EditorTemplates для разных с той же дочерней коллекцией.
Вы можете сделать это, введя условие внутри цикла и выбрав альтернативный шаблон там (либо для всего списка, либо для порядка по порядку, просто зависит от того, как вы записываете условие)
@for (int i = 0; i < Model.Orders.Count ; i++) {
if (someCondition) {
@Html.EditorFor(c => Model.Orders[i], "OrderEditorTemplateDefault")
} else {
@Html.EditorFor(c => Model.Orders[i], "OrderEditorTemplateALTERNATE")
}
}
Извините, так много. Надеюсь, что это поможет.