2012-01-05 3 views
4

Моя модель состоит из одного основного объекта, который пользователь может добавлять и другие объекты. Добавленные объекты хранятся в List<object>, содержащихся в основном объекте, и связанных дочерних объектах.Передача данных на уровень данных

Так что если проект - это дом. Пользователь может добавить в дом количество Room объектов, которые хранятся в List<Room> RoomList. Затем каждый Room может иметь количество Furnishings, добавленное снова в каждую комнату. List<Furnishing> FurnishingsList

Вопрос в том, как реализовать это в подходе MVVM? Когда пользователь добавляет новый объект, добавьте его в ObservableCollection в ViewModel, чтобы представление обновилось и в то же время добавило его в модель, подключенную к виртуальной машине? Или я храню его в виртуальной машине до сохранения или коммита, а затем передаю его в модель?

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

Итак, когда пользователь «Редактирует» комнату. Я выпускаю EditRoomModelView, содержащий Room. Пользователь добавляет, редактирует и иным образом манипулирует мебелью в этой комнате.

При каждой команде лучше всего синхронизировать данные в Модели и ModelViee, как указано выше. Или я запишу изменения прямо в Модели, и ViewModel предоставляет только геттеры на вложенных свойствах модели. Таким образом, однако добавление объектов в списки моделей не обновляет представление. мне действительно нужно было бы добавлять данные как к ModelView, так и к модели одновременно, чтобы все было в одном состоянии.

Принадлежности для бессвязных, изо всех сил пытаясь найти хороший подход к этому, кто-нибудь uderstand, что я получаю?

ответ

3

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

Если это, по сути, вопрос, в игре есть различные факторы. Вы предпочитаете делать проверку на уровне презентации? Насколько сложным является приложение и насколько он должен быть масштабируемым? Доступны ли ваши модели просмотра в разных местах?

Итак, имея в виду все это, я могу рассказать вам, как лично я предпочитаю приближаться к этой проблеме (в частности, вопрос добавления к вам упоминания). Обычно мне нравится создавать модели представлений, которые описывают проблемы пользователей с помощью дженериков, таких как EditItemViewModel<T> или ListViewModel<T>. Итак, в графическом интерфейсе будет какой-то список номеров, связанных с ListViewModel<Room>. Эта виртуальная машина, очевидно, выставляет наблюдаемую коллекцию, а также команды для добавления, удаления, редактирования.

Итак, с моей точки зрения, уровень представления, образцовый материал, который эта виртуальная машина собирается делать, это запросы маршрутов для других задач графического интерфейса. Если вы нажмете «Добавить», чтобы добавить комнату, эта виртуальная машина отвечает за инициирование запроса с помощью команды для любого экрана/окна/все, что необходимо для добавления комнаты, которое будет иметь свою собственную виртуальную машину. Эта виртуальная машина после получения запроса на добавление передает сгенерированный объект передачи данных в домен, где будет выполняться валидация, и любые операции домена необходимы. Обычно я обрабатываю это через сервисный уровень. Теперь, если операция домена была успешной, уровень обслуживания повысит четный или обратный вызов, чтобы сообщить VM о том, что есть изменение. Когда это произойдет, список VM повторно запрашивает свою службу и соответственно обновляет свою наблюдаемую коллекцию. Теперь ваш графический интерфейс совместим с доменом по всем направлениям.

Причина, по которой я одобряю этот тип многоуровневого подхода, состоит в том, что вся бизнес-логика возникает в месте «ниже» графического интерфейса, и графический интерфейс не должен касаться этого события. Концептуально GUI просто говорит: «Здесь, на уровне домена, пользователь хочет добавить это - сделайте все это, и пусть любые заинтересованные компоненты GUI узнают, когда вы закончите, чтобы они могли обновляться».

То, что я описываю здесь, естественно, потребует некоторых накладных расходов по сравнению с простой, сквозной схемой или схемой, в которой виртуальные машины просто повторно отображают свойства на каком-либо объекте модели. Но, лично, я думаю, что преимущество, полученное в результате развязки, стоит того, особенно при расширении приложения. Это дает вам возможность коренным образом изменить внутренние взаимодействия модели домена, не изменяя код уровня представления, лизать.

+0

Спасибо Эрик, Когда я успешно передаю новый объект до уровня домена и он хранится в 'List ', как я могу обновить ObservableCollection виртуальной машины, который представляет «Список »? Описывает ли уровень сервиса повторный экземпляр ObservableCollection, чтобы отразить изменения? –

+0

У меня не было бы ничего ниже уровня представления, даже знаю, что ObservableCollection (т. Е. Нет ссылки на сборку WPF, которая его содержит).Как обычно у меня есть компоненты GUI, которые уведомлены об этом, это использование событий или обратных вызовов. Для простого примера рассмотрим две виртуальные машины со ссылкой на один и тот же экземпляр службы. VM A сообщает службе добавить комнату, и служба делает любую магию, чтобы добавить комнату. Когда он будет завершен и успешный, он вызывает событие, которое слушает VM B. Когда событие поднимается, VM B повторно запрашивает услугу для всех комнат ... –

+0

В реальной реализации сам домен обрабатывал бы добавление, а затем поднимал событие, которое служба будет потреблять и ретранслировать на виртуальную машину. Но идея здесь такова: виртуальные машины просто знают, как спросить сервис для объектов (POCO/DTO) и как передать их для таких операций, как обновление. Таким образом, связь между сервисом и виртуальной машиной заключается в том, что VM будет запрашивать объекты (Get/GetAll) и запрашивать операции (Add, Edit и т. Д.). VM также прослушивает событие службы, называет его «OnDirty», который сообщает виртуальной машине, когда она может быть не синхронизирована с доменом. Затем VM несет бремя повторного запроса. –

2

Первое: View это зеркало вашего DataModel, так всегда добавить первый к Model и только после того, как думаю, если это нажать на Vm или View.

Второе: ViewModel это мост, который соединяет ваш Model с View, но это не значит, что он должен быть структурирован таким же образом Model было сделано. Если вы хотите показать пользователю все дочерние коллекции, вы должны разоблачить их как свойства и построить их отношения parent-child internaly в VM или в VM имеют только «сырые» коллекции и имеют эффективные отношения между ними в DataModel.

+0

Я не согласен с утверждением «всегда добавляйте сначала к модели и только после того, как думаете, что она нажимает на Vm или на View», нет ничего плохого в моделях просмотра, создающих другие экземпляры модели представлений, например OrderViewModel, создающие новые экземпляры OrderLineViewModel. – ColinE

+0

@ColinE: если использование добавляет новый объект, imo, неприемлемо, чтобы он заканчивался на уровне UI. Ожидание чего? Это не «веб-разработка», мы иногда сохраняем данные на уровне «Ui», чтобы сделать валидацию, агрегирование ... поскольку трассировка данных является дорогостоящей, но здесь, в «deskto world», нет никакой причины, почему в любой момент из моего жизненного цикла приложения Я не могу спросить «модель» о текущем состоянии и не имеет действительного ответа. – Tigran

2

Из описания приложения, которое вы описываете, это звучит так, как ваш слой модели представления не сильно изменяет или не формирует вашу модель. Таким образом, я сделал бы различные адаптеры свойств/моделей get-model для объектов моделированных объектов. Таким образом, ваша модель будет немедленно обновляться при изменении модели представления.

Однако ... если вам нужно предоставить функциональность «отменить», то есть пользователь открывает модальную форму для редактирования некоторой модели представления, но затем отменяет, а не редактирует OK, этот простой подход не будет работать.

Сроки, когда вы фиксируете уровень модели, редко имеют большое значение, потому что это, как правило, не трудоемкий процесс.Что более важно, когда состояние модели сохраняется. Это часто вызвано явным вызовом команды сохранения, которая отправляет модель службе сохранения (файл/облако и т. Д.)

Смежные вопросы