Должны ли мы связать представление со свойством модели или ViewModel должен иметь свое собственное ..?

21

Я начинаю проект со следующей технической средой: .Net 4.0, Entity Framework 4.0, WPF с архитектурой MVVM

Я видел много примеров в сети, несколько книг с этой средой. В некоторых примерах авторы имели эту идею:

  1. Viemodel будет иметь экземпляр класса Model (Entity Framework Entity, например, Person)
  2. Привязать элементы управления представлением WPF к свойствам модели

Хотя некоторые авторы сделали:

  1. Viemodel выставит все свойства модели.
  2. Свяжите элементы управления представлением WPF со свойствами ViewModel, а не напрямую с моделью.

Так будет ли хорошей идеей позволить представлению связывать свойства из модели, а не показывать собственную модель представления? Или что является более предпочтительным?

Правин Патил
источник
Лично я нахожу, что раскрытие свойств модели приводит к хорошему разделению вашего уровня данных и логических слоев.
Алекс Хоуп О'Коннор

Ответы:

25

Я думаю, что многие программисты сначала пытаются использовать ярлык привязки непосредственно к модели, но по моему опыту это имеет некоторые существенные недостатки. Основная проблема заключается в том, что если ваша сущностная модель сохраняется с помощью NHibernate или подобного, то, как только представление обновляет свойство модели, NHibernate может сохранить эти изменения в базе данных. Это не работает для экранов редактирования, которые имеют кнопку Сохранить / Отменить. На самом деле, он может подождать и сохранить все как пакет, но идея в том, что когда вы меняете модель, вы делаете это.

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

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

Учитывая простоту авто-свойств, я предлагаю всегда привязывать View к ViewModel, а не к Model. Он последовательный, простой и дает вам максимальную гибкость для поддержки изменений в будущем.

Скотт Уитлок
источник
Мне нравится твой ответ. +1 за упоминание Edit / Save Screen. Но тогда было бы сложно написать свойства дважды - один раз в модели и снова в view-модели. Это также увеличит время разработки. Как вы думаете, это оправданно ...?
Правин Патил
9
@Pravin Patil - fwiw, каждый раз, когда я использовал этот ярлык, я проклинал себя позже, когда мне пришлось вернуться и исправить это. Относительно мало усилий для повторной реализации свойств в ViewModel, особенно если они доступны только для чтения (потому что вы можете использовать автоматически реализуемые свойства с частным установщиком). Дело в том, что в большинстве случаев Модель представляет собой другую структуру данных, чем ViewModel. Оставьте себе возможность изменять модель, не влияя на вид. Чем меньше вам нужно изменить представление, тем лучше, потому что представление сложно проверить.
Скотт Уитлок
4
@ Скотт Уитлок: Я занимаюсь разработкой приложений WPF с NHibernate уже два года, и у меня никогда не было проблем с привязкой напрямую к модели. Фактически, когда изменяется свойство модели, это в основном одно и то же усилие для изменения, независимо от того, к чему вы привязаны. И когда позже мне действительно понадобится выполнить некоторую маршрутизацию в самой ViewModel, тогда не стоит тратить время, прежде чем оно мне понадобится. Я придерживаюсь подхода YAGNI (пока) и не испытываю трудностей. Я думаю, что вы и другие здесь немного догматичны в этом вопросе.
Сокол
16

Дело в ViewModelтом, что это модель View.

Вы должны привязывать ViewModelк View, а не какие-либо Modelсвойства (не напрямую, во всяком случае).

Одед
источник
8

Я считаю, что оба метода приемлемы

Связывание только с ViewModel является подходом «MVVM-purist» и приводит к лучшему разделению между слоями. Привязка к модели обычно быстрее и удобнее.

Если у меня нет веской причины полностью разделить слои (размер проекта, будущие проблемы с техническим обслуживанием, тип модели, с которой я работаю, и т. Д.), Я буду привязываться к модели.

Рейчел
источник
7

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

Псевдокод:

 {Binding: MyViewModel.MyModel.Name}

Это сделано для уменьшения количества свойств «Fluff» в модели представления, к сожалению, это также плохая идея в долгосрочной перспективе. Концепция модели представления состоит в том, чтобы гарантировать, что представление не принимает зависимость от модели. При связывании через вас теперь необходимо убедиться, что ваша модель содержит свойство с именем name, иначе ваша реализация будет нарушена.

Однако если вы привязываете только модель представления, вы можете изменить модель, и представление никогда не узнает, поскольку оно только увидит свойство с именем Name в модели представления.

Теперь это можно смягчить при определенных обстоятельствах, если ваша модель основана на интерфейсе. Таким образом, если интерфейс имеет IBaseDetails, который предоставляет свойство ModuleName, вы можете:

Псевдокод:

 {Binding: MyViewModel.MyModel.ModuleName}

Пока любая из ваших Моделей удовлетворяет интерфейсу IBaseDetails, ваш золотой, знайте, однако, что это крайний случай, и в целом вы на 90% всегда лучше оберните свою модель представления вокруг любых моделей, которые она покрывает.

DeanMc
источник
2

Если вы видите много трений, пытаясь перейти от Model -> ViewModel, попробуйте что-то вроде AutoMapper. Это удаляет скуку, связанную с копированием свойств вручную.

Брайан Бетчер
источник
1

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

Используйте подход Угловой Реактивной Формы. Вы создаете группу форм, используя некоторую информацию View Model, но позже вам нужно получить доступ к форме. Значения, чтобы получить значения и копировать, делают значения для модели с использованием любого автоматического сопоставления или руководства. Я думаю, что нет ничего более прекрасного, чем привязка к свойствам в модели представления, скажем, например, у меня есть страница представления проекта, где у меня есть имя проекта, имя клиента и т. д.

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

То же самое может быть для обновления модели, в случае сохранения / отмены нет ничего более чистого.

Иван Карменатес Гарсия
источник
этот пост довольно трудно читать (стена текста). Не могли бы вы изменить его в лучшую форму?
комнат
Там вы идете, ура.
Иван Карменатес Гарсия