Использование DisplayTemplate (с DisplayFor) для каждого элемента в коллекции

Я создал DisplayTemplate для класса Comment и разместил его внутри Comment/DisplayTemplates/Comment.cshtml.

Comment.cshtml правильно напечатан:

@model Comment

Затем у меня есть частичное представление, которое принимает модель IEnumerable<Comment> для модели. Там я просматриваю коллекцию и хочу использовать DisplayTemplate для класса Comment. Представление в его целостности:

@model IEnumerable<Comment>

@foreach (var comment in Model.Where(c => c.Parent == null)) { 
    @Html.DisplayFor(model => comment)
}

Однако, я получаю сообщение об ошибке в строке Html.DisplayFor:

Элемент модели, переданный в словарь, имеет тип "System.Int32", но для этого словаря требуется элемент модели типа "System.String".

Как я могу вызвать DisplayTemplate для каждого элемента в цикле foreach?

Ответ 1

Вместо того, чтобы иметь представление, которое принимает IEnumerable<Comment>, и все, что он делает, - это цикл через коллекцию и просто вызвать правильный шаблон отображения:

@Html.DisplayFor(x => x.Comments)

где свойство Comments является IEnumerable<Comment>, которое автоматически выполняет цикл и отображает шаблон отображения Comment.cshtml для каждого элемента этой коллекции.

Или, если вам действительно нужен такой взгляд (не знаю почему), вы могли бы просто:

@model IEnumerable<Comment>
@Html.DisplayForModel()

Что касается предложения Where, которое вы используете там, вы должны просто удалить его и делегировать эту задачу контроллеру. Ответственность диспетчера заключается в подготовке модели представления, а не в представлении, выполняющем такие задачи.

Ответ 2

В то время как принятый ответ работает хорошо в большинстве случаев, есть и другие случаи, когда нам нужно знать индекс элемента при рендеринге (т.е. добавлять пользовательский javascript, который генерирует ссылки на каждый элемент на основе их индекса).

В этом случае DisplayFor все еще можно использовать в цикле следующим образом:

@model IEnumerable<Comment>

@for (int index = 0; index < Model.Count(); index++)
{
     @Html.DisplayFor(model => model[index])
}