Чи слід ми прив'язувати погляд до властивості моделі чи ViewModel повинен мати власне ..?


21

Я починаю проект із наступного технічного середовища: .Net 4.0, Entity Framework 4.0, WPF з MVVM Architecture

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

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

Хоча деякі автори робили:

  1. Viemodel розкриє всі властивості моделі.
  2. Прив’яжіть елементи керування подання WPF до властивостей ViewModel, а не безпосередньо до моделі.

Тож чи є гарною ідеєю дозволити представленням пов'язувати властивості з моделлю, а не viewmodel виставляти власні? Або що є більш кращим?


Особисто я знаходжу, що виявлення властивостей моделі призводить до гарного відокремлення вашого шару даних та логічних шарів.
Алекс Хоуп О'Коннор

Відповіді:


25

Я думаю, що багато програмістів спочатку намагаються скористатися ярликом прив’язки безпосередньо до моделі, але, на мій досвід, це має деякі основні недоліки. Основна проблема полягає в тому, що якщо модель вашої сутності зберігається NHibernate або подібною, то як тільки View оновлює властивість моделі, NHibernate може зберегти ці зміни в базі даних. Це не добре працює для екранів редагування, на яких є кнопка Зберегти / Скасувати. Насправді він може зачекати і зберегти все як партію, але ідея полягає в тому, що, змінюючи модель, ви здійснюєте свої зміни.

Таким чином, ви все ще можете уникнути прив’язки безпосередньо до властивостей моделі на екранах, доступних лише для читання, але тоді у вас виникне невідповідність.

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

Враховуючи простоту автоматичних властивостей, я пропоную завжди прив'язувати Перегляд до ViewModel, а не до Моделі. Це послідовно, просто і дає вам найбільшу гнучкість для підтримки змін у майбутньому.


Мені подобається ваша відповідь. +1 для згадки Редагувати / Зберегти Екран .. Але тоді було б неприємно писати властивості двічі - один раз у моделі та знову в view-model. Це також збільшить час розробки. Ви вважаєте, що це виправдано зробити так ...?
Pravin Patil

9
@Pravin Patil - fwiw, кожного разу, коли я брав цю ярлик, я проклинав себе пізніше, коли мені довелося повернутися назад і виправити це. Досить мало зусиль для повторної реалізації властивостей ViewModel, особливо якщо вони доступні лише для читання (адже ви можете використовувати власно реалізовані властивості з приватним сеттером). Справа в тому, що в більшості випадків Модель є іншою структурою даних, ніж ViewModel. Залиште собі гнучкість змінити Модель, не впливаючи на Вигляд. Чим менше вам доведеться змінити Вигляд, тим краще, тому що Перегляд важко перевірити.
Скотт Уїтлок

4
@Scott Whitlock: Я розробляю програми WPF разом з NHibernate вже два роки і ніколи не мав жодних проблем, пов'язаних безпосередньо з моделлю. Насправді, коли властивість моделі змінюється, це здебільшого те саме зусилля для зміни, незалежно від того, до чого ви зв'язані. І коли мені справді потрібно буде зробити деяку маршрутизацію в самому ViewModel пізніше, тоді не варто було вкладати час, перш ніж мені це було потрібно. Я дотримуюся підходу YAGNI (поки що) і не маю труднощів. Я думаю, що ви та інші тут трохи догматичні щодо цього питання.
Сокіл

16

Суть a ViewModelполягає в тому, що вона є моделлю View.

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


8

Я вважаю обидва методи прийнятними

Прив'язка лише до ViewModel - це підхід "МВВМ-пурист" і призводить до кращого поділу між шарами. Прив’язання до Моделі зазвичай швидше і зручніше.

Якщо у мене немає вагомих причин повністю розділити шари (розмір проекту, проблеми з майбутнім обслуговуванням, тип моделі, з якою я працюю тощо), я прив'язуюсь до моделі.


7

Я думаю, що ви бачите це поняття, яке називається зв'язувати через, тобто якщо у вашої моделі є властивість під назвою ім'я, а ваша модель перегляду відкриває це властивість без додаткового редагування чи перетворення, то ви можете прив’язатись до моделі, щоб це було.

Псевдокод:

 {Binding: MyViewModel.MyModel.Name}

Це робиться для зменшення кількості властивостей "Fluff" на моделі перегляду, на жаль, це також погана ідея в довгостроковій перспективі. Концепція моделі перегляду полягає в тому, щоб погляд не приймав залежності від моделі. Прив'язуючи вас тепер, ви повинні переконатися, що ваша модель містить властивість під назвою name, інакше ваша реалізація буде порушена.

Якщо ви прив'язуєте лише те, що стосується моделі перегляду, проте ви можете змінити модель, і представлення ніколи не дізнається, оскільки воно лише коли-небудь побачить властивість з назвою Name на моделі view.

Тепер це можна пом'якшити за певних обставин, якщо ваша модель базується на інтерфейсі. Отже, якщо в інтерфейсі був IBaseDetails, який відкрив властивість ModuleName, ви можете:

Псевдокод:

 {Binding: MyViewModel.MyModel.ModuleName}

Поки будь-яка з моделей, які ви створюєте, задовольняє інтерфейс IBaseDetails, ваша золота, майте на увазі, що це кращий випадок, і взагалі вам на 90% завжди краще обернути свою модель перегляду навколо будь-яких моделей, які вона охоплює.


2

Якщо ви бачите багато тертя, намагаючись перейти від Model -> ViewModel, спробуйте щось на кшталт AutoMapper. Це видаляє нудьгу, пов’язану з властивостями копіювання, вручну.


1

Я потрапив сюди лише тому, що в мене були ті самі сумніви, і я переконався, що завжди буду прив’язуватися до перегляду моделі, а не до моделі.

Візьміть підхід углової реактивної форми. Ви створюєте групу форм, використовуючи деяку інформацію "Перегляд моделі", але пізніше ви повинні отримати доступ до форми. Значення для отримання значень та копіювання робить значення для моделі за допомогою будь-якого автоматичного картографування чи посібника. Я думаю, що немає кращої речі, ніж призначення ставок для властивостей у моделі перегляду, скажімо, наприклад, що у мене є сторінка перегляду проекту, на якій я назва проекту, ім'я клієнта тощо.

Існує зв’язок між проектом та клієнтом, оскільки проект має клієнта. Тож на цьому рівні я не повинен дбати про такі відносини, мені просто потрібно візуально показати ім'я проекту та ім’я клієнта у поданому вигляді, тому я помістив 2 властивості у назву проекту та ім'я клієнта, щоб я прив’язував елементи перегляду до обох їх, пізніше я буду хвилюватися про надання значень тим властивостям у коді позаду, а потім з будь-якої структури, яка має модель.

Те саме могло б бути і для оновлення моделі у випадку збереження / скасування нічого більш чистого.


цю публікацію досить важко читати (стіна тексту). Ви б не хотіли відредагувати його на кращу форму?
гнат

Ось ви йдете, ура.
Іван Карменатес Гарсія
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.