Могу ли я иметь именованный шаблон отображения для коллекции

У меня есть дисплей для коллекции SomeObject

public List<SomeObject> SomeObjects

@Html.DisplayFor(m => m.SomeObjects)

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

@Html.DisplayFor(m => m.SomeObjects, "NameOfTemplate")

Когда я это сделаю, я получаю следующее сообщение ... Я уже использовал именованные шаблоны отображения раньше, но, возможно, это работает только для примитивных типов - строк и т. Д.?

'System.Collections.Generic.List1[SomeObject]', но для этого словаря требуется элемент модели типа 'SomeObject'.

Добавление кода в качестве запроса

"Тестовый" DisplayTemplate

@model ViewModels.SomeObject

<p class="Namme">
    <span>@Model.Name</span>
</p>

SimpleViewModel

 public class SomeObject
    {
        public string Name { get; set; }
    }

Свойство в ParentViewModel

public List<SomeObject> SomeObjects { get; set; }

Cshtml файл ..

@Html.DisplayFor(m => m.SomeObjects, "Test")

Для меня это простой вопрос: можно ли использовать именованный шаблон с коллекцией или нет? Это еще одно ограничение mvc ..

Привет, Джон


person John    schedule 13.11.2013    source источник
comment
Убедитесь, что модель в шаблоне Display относится к тому же типу, который вы передаете через расширение для бритвы DisplayFor. Похоже, это не общий список в вашем шаблоне отображения. Например, в вашем шаблоне: «@model IList ‹SomeObject›» вместо «@model SomeObject»   -  person gdp    schedule 13.11.2013
comment
Я попробовал то, что вы предложили, и это не сработало. Я понимаю, что модель для displayTemplates должна быть единой, а не коллекцией .. Вот что я пробовал, и ошибка @model IList ‹SomeObject› HttpCompileException не была обработана пользовательским кодом. Внешний компонент вызвал ошибку исключения.   -  person John    schedule 13.11.2013
comment
Можете ли вы опубликовать полный код, включая шаблон. По сути, все, что вы проходите через Display For, должно быть типом модели для шаблона дисплея. Попробуйте поместить "@ Html.DisplayFor (m =› m .SomeObjects.First (), TemplateName) ". Похоже, вы просто передали неправильный тип модели. Включите также код модели для вызывающей страницы CSHTML.   -  person gdp    schedule 13.11.2013


Ответы (2)


Да, вы передаете список SomeObject в шаблон отображения, когда он ожидает:

@model ViewModels.SomeObject

Вам либо нужно изменить шаблон на что-то вроде этого и принять список в качестве модели представления:

@model IList<ViewModels.SomeObject>

@foreach (var item in Model) {
<p class="Namme">
    <span>@item</span>
</p>
}

Или измените то, что вы передаете в шаблон отображения в родительском файле CSHTML, и сделайте его одним объектом SomeObject примерно так:

public List<SomeObject> SomeObjects

@foreach (var item in Model.SomeObjects) {
    Html.DisplayFor(item, "TemplateName")
}

На него сложно ответить, потому что я не уверен, чего вы пытаетесь достичь и что такое SomeObject, но это должно указать вам в правильном направлении.

person gdp    schedule 13.11.2013
comment
Спасибо gdp .. Это ограничение mvc, поэтому ... При передаче списка (когда не именованный шаблон отображения работает нормально, mvc выполняет цикл за меня) Как только вы используете именованный шаблон, он передаст коллекцию, так что да, модель должен быть коллекцией, следовательно, потребуется цикл for внутри. Для меня это было бессмысленно, так как у меня был цикл for в моем вызывающем коде, я хотел использовать шаблон отображения, чтобы я мог его исключить. Как уже упоминалось, это не именованный шаблон, он отлично работает ... ах. живи и учись :) - person John; 13.11.2013
comment
Просто у вас был неправильный тип модели в вашем пользовательском шаблоне отображения. Изменение этого на список в шаблоне - это то, что MVC будет делать в любом случае под капотом, используя только это: '@ Html.DisplayFor (m = ›m.MyCollection)'. - person gdp; 13.11.2013
comment
правда, но внутри моего шаблона, если я попытаюсь получить доступ к элементам объекта, мне понадобится цикл for ... чего я хотел избежать ... когда это не именованный шаблон, мне не нужен цикл. это для меня главное отличие .. - person John; 13.11.2013
comment
Да, вы не можете этого избежать, к сожалению, если вы хотите более детальный контроль, вам нужно зациклить модель. - person gdp; 13.11.2013

Тип SomObjects - List<SomeObjects>, поэтому шаблон представления должен иметь соответствующую модель:

@model `ICollection<ViewModels.SomeObject>`

Я предпочитаю не ограничивать представление конкретным List<> классом, а использовать интерфейс.

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

person Anders Abel    schedule 13.11.2013
comment
Андерс, если я это сделаю, мне нужно будет перебрать его с помощью цикла for. Смысл того, что я использовал шаблон, заключался в том, чтобы удалить цикл for с вызывающей страницы. Поместив единственный объект в качестве модели, мне не нужен цикл, а mvc позаботится об итерации. Все это работает нормально, пока я не попробую именованный шаблон, о котором мой вопрос, так как у меня много работы с коллекциями .. Связано с этим сообщением .. stackoverflow.com/questions/8002059/ - person John; 13.11.2013
comment
Проблема в том, что вы можете указать MVC, какой шаблон использовать для всей коллекции, тогда он использует свою внутреннюю логику для поиска шаблона для каждого элемента. Если это то, что вы хотите контролировать, вам, вероятно, не повезло, поскольку я не знаю способа передать шаблон отображения на этот второй шаг поиска. - person Anders Abel; 13.11.2013