MVVM - что должно содержать что ... что должно создавать что - PullRequest
3 голосов
/ 16 марта 2009

У меня есть правильный барни, который думает, как все сочетается, используя шаблон MVVM. На практике все кажется довольно простым, но, пытаясь реализовать его, я нарушаю другие правила, по которым пытаюсь кодировать.

В качестве дополнительного примечания я пытаюсь реализовать шаблон, используя Flex, а не Silverlight или WPF, поэтому, если кто-то может дать веские причины, почему этого не следует делать, тогда я бы хотел их услышать.

У меня проблема с несколькими взглядами. Иногда мне приходится отображать два просмотра на странице одновременно; иногда я снова переключаюсь на один вид. В моем обычном мозге Flex у меня был бы основной вид с кодом позади, который содержал бы все мои другие представления (в равной степени с кодами сзади). Этот основной вид будет затем переключать другие отдельные виды.

Когда я пытаюсь реализовать это в MVVM, я пытаюсь придерживаться принципов MVVM, используя привязку, которая отделяет мой Views от ViewModels. Допустим, я создаю ViewModel для состояния приложения, и мой ApplicationView связывается с этими данными и выполняет все переключения подвидов.

Теперь, где я должен создать свои модели представления для моих подпредставлений? Я пробовал внутри ApplicationView - это не казалось правильным. А затем я попытался за пределами представления приложения и передачи его экземпляра в ApplicationView, а затем мои подмодели связались с ним. Я что-то пропустил? Похоже, что ни один из этих методов не подходит для всей цели попытки отделить это.

Буду очень признателен за любые хорошие книги или ссылки, объясняющие эту проблему.

Ура, Джеймс

Ответы [ 3 ]

7 голосов
/ 20 марта 2009

Подход, на который вы ссылаетесь, это композиция ViewModel. Это где у вас есть несколько сложных частей представления, которые необходимо привязать к своей собственной сущности ViewModel. Подход влечет за собой создание корневой ViewModel со свойствами для каждого дочернего ViewModel. Затем корневой вид привязывается к корневой модели представления, и каждый вид (независимо от того, отображается ли он или свернут) привязывается к соответствующему свойству в корневой модели представления.

ViewModel будет выглядеть так:

public class RootViewModel 
{
   ChildViewModelA ChildA { get; set; }
   ChildViewModelB ChildB { get; set; }
}

Вид будет выглядеть так:

<Grid>
   <ChildViewA DataContext="{Binding ChildA}" />
   <ChildViewB DataContext="{Binding ChildB}" />
</Grid>

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

ViewModel будет выглядеть так:

public class RootViewModel 
{
   public List<ViewModel> ChildWorkspaces { get; set; }
   public ViewModel ActiveWorkspace { get; set; }

   public RootViewModel() 
   {
      ChildWorkspaces.Add(ChildViewModelA);
      ChildWorkspaces.Add(ChildViewModelB);
   }
}

Вид будет выглядеть так:

<Grid>
   <Grid.Resources>
      <DataTemplate DataType="ChildViewModelA">
          <ChildViewA />
      </DataTemplate>
      <DataTemplate DataType="ChildViewModelB">
          <ChildViewB />
      </DataTemplate>
   </Grid.Resources>
   <ContentControl Content="{Binding ActiveWorkspace}" />
</Grid>

Это приведет к тому, что соответствующее визуальное представление будет выбираться на основе типа фактического объекта, хранящегося в ActiveWorkspace.

Простите, мой ответ был в WPF. Я изо всех сил старался не попасться в синтаксис всего этого: -)

Как видите, множественность «ViewModel» может быть неоднозначной. Часто мы сталкиваемся с необходимостью создания нескольких подобъектов, чтобы правильно структурировать ViewModel. Но все сущности ViewModel будут где-то внутри корневого объекта View Model.

При реализации MVVM в WPF я предпочитаю выводить, какой визуальный элемент неявно применять к контексту данных (как показано во второй половине этого ответа). В более сложных сценариях я предпочитаю использовать DataTemplateSelector для принятия такого решения. Но в очень простых случаях вы можете явно применять DataContext либо в C # / ActionScript, либо декларативно через привязки.

Надеюсь, это поможет!

3 голосов
/ 17 марта 2009

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

Самый простой подход, который я видел к реализации MVVM во Flex, - это поместить отдельные ViewModel в приложение Model / ModelLoactor. ModelLoactor содержит любые глобальные данные, а также служит средством доступа ко всем ViewModels. ApplicationViews может затем связываться с их конкретным ViewModel через ModelLocator, в то время как ViewModels может обновляться как с помощью команд, так и посредством привязки к их родительскому ModelLocator. Одним из преимуществ этого подхода является то, что вся логика данных локализована; конечно, это также можно рассматривать как недостаток, поскольку центральная ModelLocator является хрупкой на ощупь из-за жестко закодированных ссылок на все ViewModels.

Я видел более чистые подходы, работающие с использованием среды Mate. Мате допускает гораздо более децентрализованную инъекцию ViewModels в соответствующий ApplicationViews. (Я полагаю, что это также может быть достигнуто с помощью Swiz, я просто не так хорошо знаком с этой структурой). С Mate каждый ApplicationView имеет ViewModel, введенный с помощью карты. Что хорошо в этом подходе, так это то, как ViewModels может быть обновлено с помощью EventMap (Mate-версия FrontController). По сути, ваш ApplicationViews будет отправлять события, которые обрабатываются одним или несколькими EventMaps, и эти Карты затем могут вносить изменения в один или несколько из ViewModels. Этот подход позволяет жесту или событию пользователя из одного ApplicationView изменять состояние сразу нескольких ViewModels. Кроме того, поскольку эта логика извлечена в Mate EventMaps, очень легко изменить способ обработки событий или изменения ViewModels. Конечно, главный недостаток этого подхода заключается в том, что вы берете на себя обязательство использовать Mate в качестве фреймворка, который может не подходить в зависимости от требований проекта.

Надеюсь, это поможет!

0 голосов
/ 09 февраля 2011

Я хотел бы поделиться сравнением, которое я написал для MVVM (Silverlight) и PresentionModel (Flex). Он показывает, как две реализации одного и того же шаблона отличаются / сравниваются:

http://houseofbilz.com/archives/2010/12/29/cross-training-in-silverlight-flexmvvm-vs-presentation-model/

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