Несколько моделей отправлены в один экземпляр представления - PullRequest
8 голосов
/ 05 января 2010

Моя терминология, вероятно, здесь далеко, но в основном я пытаюсь передать несколько моделей данных в представление. Чтобы помочь поставить вопрос в контексте, возьмите этот пример:

Скажи, что я веду блог. При входе в систему я хочу, чтобы на главном экране отображался список всех новых неутвержденных комментариев, а также список недавно зарегистрированных пользователей и список самых последних отправленных сообщений в блоге.

Большинство обсуждений, которые я видел, предлагают строго типизировать страницу представления, чтобы ее можно было вызвать с помощью чего-то вроде «return View (RecentComments)» и перебирать комментарии в представлении, или приводить модель данных как «var NewUsers». = (MembershipUserCollection) ViewData.Model ". В идеале мне нужен «правильный» или, по крайней мере, «правильный» способ прохождения нескольких моделей при сохранении надлежащего логического разделения.

Ответы [ 8 ]

14 голосов
/ 05 января 2010

Один из способов - создать новый тип, который инкапсулирует обе части данных модели:

public class MyBigViewData {
    public SubData1 SubData1 { get; set; }
    public SubData2 SubData2 { get; set; }
}

public class SubData1 {
    ... more properties here ...
}

public class SubData2 {
    ... more properties here ...
}

Другой способ - сохранить «основные» данные модели в виде строго типизированных данных и сохранить другие данные в данных представления в виде элементов словаря:

ViewData["username"] = "joe"; // "other" data
ViewData["something"] = "whatever"; // "other" data
ViewData["subdata1"] = new SubData1(...);
return View(myRealModelData);

Преимущество второго подхода заключается в том, что вам не нужно делать ничего особенного: он работает прямо из коробки.

8 голосов
/ 05 января 2010

В прошлом я написал класс, в котором содержались экземпляры обоих классов, которые мне понадобятся для представления.

е

public class City{
public Mall TheMall;
public School TheSchool;
}

Тогда ваше представление будет строго напечатано как Город, и вы будете использовать Model.TheMall.Property и Model.TheSchool.Property для доступа к тому, что вам нужно

EDIT

Это пример того, что другие плакаты имеют в виду, создавая объект с обоими объектами в качестве полей / свойств

3 голосов
/ 05 января 2010

Способ передачи нескольких моделей в представление состоит в создании так называемой модели представления формы, в которой есть другие ваши модели.

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

Имеет смысл?

редактировать

Кстати: модель представления формы - это просто класс. это не особый тип, как можно было предположить из моего ответа.

3 голосов
/ 05 января 2010

К сожалению, единственный способ выполнить передачу нескольких объектов - это либо создать объект с обоими объектами в качестве полей / свойств, либо использовать слабо типизированный массив.

2 голосов
/ 06 января 2010

В дополнение к моему другому ответу, другим способом сделать это было бы не строго печатать представление и главные страницы в директиве page, а вместо этого использовать общие расширения ViewData на основе типов из MVC Contrib . Эти расширения в основном используют полное имя типа в качестве ключа словаря ViewData. По сути, преимущества типизации такие же, как и у строго типизированного подхода к странице, с меньшими затратами на классы с точки зрения количества требуемых классов модели представления. Тогда в своих действиях вы делаете

ViewData.Add<Car>(car);
ViewData.Add<LayoutAData>(layoutAData);

и в представлениях вы делаете

<%= ViewData.Get<Car>().Color %>

и на главной странице вы делаете

<%= ViewData.Get<LayoutAData>().Username %>

Вы можете кэшировать эти вызовы Get <>, встроенные в представления, чтобы уменьшить стоимость приведения несколько раз.

1 голос
/ 16 января 2012

Одна вещь, которую никто, по-видимому, не упомянул, - это то, что в исходном примере спрашивающих, возможно, имеет смысл создать представление из серии дочерних действий, которые обрабатывают свою собственную область функциональности, а не создавать модель мега-представления. Таким образом, такие компоненты, как неутвержденные сообщения и т. Д., Можно использовать повторно.

Это также дает лучшую инкапсуляцию.

1 голос
/ 30 сентября 2011

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

1 голос
/ 05 января 2010

После работы с большим приложением ASP.NET MVC я обнаружил, что наиболее продуктивный подход при минимизации приведения во время выполнения основан на использовании обобщенных элементов для имитации вложенной структуры представлений. По сути, представления получают свой собственный тип данных. Обычно это либо доменные объекты, либо коллекции доменных объектов, которые содержат метаданные. Универсальные версии этих типов доступны на всех возможных главных страницах, принимая параметр типа, который определяет данные, относящиеся к главной странице.

public class Car {
  // can be used as a model
} 

public class CarCollection: Collection<Car> {
  public BodyTypes BodyType {get;set;}
  public Colors Color {get;set;}
  // can also be used as a model
}

public interface ILayoutModel<TLayout> {
  TLayout LayoutModel {get;set;}
}

public class CarView<TLayout>: Car, ILayoutModel<TLayout>  {
  // model that can be used with strongly-typed master page
}

public class CarCollection<TLayout> : CarCollection, ILayoutModel<TLayout> {
  // model that can be used with strongly-typed master page
}

public class LayoutAData {
  // model for LayoutA.master
}

public class LayoutBData {
  // model for LayoutB.master
}

Также возможно инвертировать универсальность, но, поскольку, по моему мнению, данные определяют макет, данные представления должны доминировать над данными макета. LayoutA.master будет производным от ViewMasterPage<ILayoutModel<LayoutAData>>, а LayoutB.master будет производным от ViewMasterPage<ILayoutModel<LayoutBData>>. Благодаря этому данные представления и данные макета разделяются согласованным, строго типизированным и гибким способом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...