|
Модератор
|
|
Классы Model в View14.02.2019, 23:08. Показов 5073. Ответов 24
Такой концептуальный вопрос.
Есть, допустим, класс Person (ID, Name, Family) в библиотеке Model (ModelLib). Модель построена, всё отлажено. Выдаёт данные, в том числе типа Person. Приступаем к созданию View. Но View не имеет информации о классе Person и не может отобразить его свойства.
0
|
|
| 14.02.2019, 23:08 | |
|
Ответы с готовыми решениями:
24
Model View Model view controller
|
|
1524 / 914 / 329
Регистрация: 17.05.2015
Сообщений: 3,438
|
|
| 15.02.2019, 08:05 | |
|
Элд Хасп, а что отображать требуется? один экземпляр класса или массив?
0
|
|
|
1857 / 1363 / 429
Регистрация: 10.06.2011
Сообщений: 2,136
|
|
| 15.02.2019, 09:04 | |
|
Вариант 1.
Имеются ли какие-то аргументы, чтобы так нельзя было делать? В общем случае, если нужно просто отобразить данные во вью, то следует использовать класс модели. Если отображение имеет свою дополнительную логику: нужно отобразить значение, вычисленное из других свойств или объектов, обработать пользовательский ввод, иметь на уровне класса команду, то тогда следует создать для класса модели соответствующую ей вью-модель.
0
|
|
|
|
|
| 15.02.2019, 10:54 | |
|
В случае прямого биндинга модели ко View нужно всегда помнить что сделал именно так. Т.е. в случае когда ТОЧНО знаешь что расширенных действий не понадобится (как указал novikov.ea). В противном случае XAML в последствии может жутко разрастись, потом накатится VM, и, в какой либо момент времени, настанет случай кода View будет ссылаться и на VM и на модель. Что приведёт к пипец каким нервам))) и говнокоду.
Добавлено через 2 минуты Имхуется, что прямой биндинг прям вот необходим в случае простого отображения уже вычисленных данных, информационных сообщений, содержащих значения из модели, окон ошибок ввода или проверок.
0
|
|
|
Модератор
|
|||||
| 15.02.2019, 14:11 [ТС] | |||||
|
В реальных случаях могут быть и отдельные экземпляры, но чаще это проблема возникает конечно для массивов. Так как дублирование свойств одного экземпляра в VM - не затратно. Вот сейчас пытаюсь сделать приложение для работы с сервером. А там Сервер возвращает в ответах списки типизированные несколькими десятками разных классов и сами классы содержат по несколько десятков свойств. Начал делать"в лоб".... Но чувствую какая-то пурга получается. Или огромное дублирование на уровне VM, или надо делать ссылки из View и на VM, и на Model. Даже просто наследование классов VM от классов Model не спасает. Всё равно тогда приходится в View делать ссылки на базовые классы Model. Что бы не делать таких ссылок придётся делать классы VM без наследования от Model, но это приводит к большому количеству дублирующего кода. Вот если таким образом организовать решение. Насколько это будет "чисто" для MVVM ?
0
|
|||||
|
1524 / 914 / 329
Регистрация: 17.05.2015
Сообщений: 3,438
|
|||
| 15.02.2019, 14:27 | |||
Если ответ сервера нужно отобразить на вью, то сам ответ сервера уже относится к логике-представления и должен проходить во VM, с применением классов Model. Если же этот ответ будет обрабатываться - то это часть бизнес логики и должен проходить в модели, а результаты, подлежащие опубликованию, отправляться во VM. Хоть господа сверху и вещают, что допустимо биндиться напрямую к модели, если это одностороняя привязка, делать этого не не надо. Модель не должна в себе содержать данные для опубликования.
1
|
|||
|
Модератор
|
|
| 15.02.2019, 14:45 [ТС] | |
|
Рядовой, вот такой пример.
Класс Person (ID, Name, Family). Ответ от сервера приходит в формате массива, где ID, Name и Family - это элементы массива. Элементы массива в View я показать не могу. Нужны свойства. Делаю в VM наследника от Person в котором свойства берут свои значения от элементов массива базового класса. Если View меняет значения свойств, то я без проблем отправляю наследника в Model он сам там дефолтно приводится к базовому классу и сохраняется. Но! Базовый класс объявлен в Модели и View требует ссылку на Модель. Поэтому и возникла вышеуказанная схема, где классы Модели находятся в отдельной библиотеке и View получает ссылку на эту библиотеку. Но корректно ли это? Может я слишком узко смотрю и есть какое-то другое более типовое решение?
0
|
|
|
1524 / 914 / 329
Регистрация: 17.05.2015
Сообщений: 3,438
|
||
| 15.02.2019, 14:59 | ||
|
Элд Хасп, если этот Person должен быть отображен во вью, то он должен находится во VM (сам экземпляр). Базовый класс объявлен в модели и служит контейнером, который вы наполняете во VM, а вью отображает
1
|
||
|
Модератор
|
||
| 15.02.2019, 15:12 [ТС] | ||
|
Но это привело к огромному дублированию кода. Это в примере один класс с тремя свойствами. А в реале десятки классов с десятками свойств.... Возникают сомнения - на том ли я пути... Часть ответов приходит как нормальные классы. Нормально JSON десериализуются в классы со свойствами. Что с ними делать? Это же классы Модели, а не VM. Если их объявить в VM, то Модель не сможет ими пользоваться. Если Их объявить в Модели, то для View они не доступны. Их тоже использовать просто как контейнер и перезаписывать в классы VM ? Добавлено через 2 минуты И подход нужен единообразный. Если часть классов (которые приходят как массивы) использовать как контейнеры, а те что со свойствами стыковать напрямую к View - вообще, какой-то бедлам получится!
0
|
||
|
1524 / 914 / 329
Регистрация: 17.05.2015
Сообщений: 3,438
|
||
| 15.02.2019, 15:25 | ||
|
Получайте данные в модель, заполняйте класс - наследник (как вы и делали) и отправляйте во VM. А оригиналы отправляете на обработку. Это будет правильно. Данные которые идут на обработку не должны быть отображены, поэтому нельзя вью ссылаться на модель Добавлено через 1 минуту Просто надо четко для себя различать - эти отображаются, эти обрабатываются. Добавлено через 2 минуты Вместо класса можно использовать стуктуру. Тогда данные отправленные во VM - будут копиями, которые и будут отображаться. Так можно повысить скорость работы.
1
|
||
|
1595 / 600 / 185
Регистрация: 05.12.2015
Сообщений: 970
|
||
| 16.02.2019, 13:50 | ||
|
зачем объявлять во view классы модели? view это только отображения через рефлексию. какая разница какой класс. Binding работает с простыми именами типа String, по которым ищется в ссылке на объект фунция Getter. Какой там класс стоит за ним - до лампочки.
0
|
||
|
Модератор
|
|||||||||||||||||||||||||||
| 16.02.2019, 23:42 [ТС] | |||||||||||||||||||||||||||
|
Класс PersonVM расположенный в ViewModelLibrary
Теперь сделаем класс PersonM в ModelLibrary. Просто пустой класс - для примера
Вот вопрос в том, что Модель составляется для работы с данными. В ней есть классы предназначенные для этой работы. В частном случае - это множества классов для разбора ответа от Сервера. Так как в конечном итоге эти данные для отображения поступают в View (конечно через посредство VM), то как View передать информацию об этих классах? Если не делать прямой ссылки на библиотеку содержащую эти классы, то в VM надо делать дубликаты этих классов. Даже наследование не поможет - нужны именно дубликаты. Если дать такую ссылку, то получается связь между View и Model, что нарушает "чистоту" MVVM.
0
|
|||||||||||||||||||||||||||
|
1595 / 600 / 185
Регистрация: 05.12.2015
Сообщений: 970
|
||||||||||||
| 17.02.2019, 02:22 | ||||||||||||
|
И вы удивляетесь почему ваша View просит предоставить ей класс из Model? Потому что ей надо "вытащить" все базовые свойства родительского класса(PersonM), когда она создает DataTemplate, по вашему требованию в этом коде:
Решение проблемы: уберите DataType, потому что он требует прямого доступа ко всей иерархии класса. и не создавайте жестких ссылок. Без них все работает. В событии Loaded:
0
|
||||||||||||
|
Модератор
|
|||||||||||||
| 17.02.2019, 09:42 [ТС] | |||||||||||||
|
Убрав их придётся делать шаблоны элементов, а это всё таки несколько иное. Шаблон элементов требует прописывание всего визуального поведения. Вот для примера заменив шаблон данных на такой шаблон элемента
И полностью элемент придётся прописывать так
0
|
|||||||||||||
|
1595 / 600 / 185
Регистрация: 05.12.2015
Сообщений: 970
|
||||||||||||
| 17.02.2019, 11:07 | ||||||||||||
|
я написал, что надо убрать DataType из определения в шаблонах данных, если объяснять на пальцах, то надо вместо
0
|
||||||||||||
|
Модератор
|
||
| 17.02.2019, 13:48 [ТС] | ||
|
Да, моя невнимательность! Не так понял Вас. ![]() Это решает часть проблем. Но ещё часть остаётся. Главное приходится создавать все привязки в "слепую", так как в конструкторе View эти свойства не видны. И отладить View можно будет только после создания приложения целиком. Но по концепции MVVM, View создаётся ещё до создания ViewModel и отлаживаться она должна на ViewModelDD, которая заполняется в Xaml. Даже, если не использовать DataType , то отладить View не получится.
0
|
||
|
1595 / 600 / 185
Регистрация: 05.12.2015
Сообщений: 970
|
|
| 17.02.2019, 14:43 | |
|
так вписывайте DataType где надо и отлаживайте, но с тем ограничением, что класс к которому она обращается, не должен уходить корнями в сборку, которую вы не хотите включать.
Вот и все.
0
|
|
|
Модератор
|
||
| 17.02.2019, 15:00 [ТС] | ||
![]() Но суть-то темы и моего интереса и была в том, как быть когда в View нужна информация о классах из Model ? Ну, не обойтись без этого ! Конечно, не вообще, а в конкретном случае. Вот у меня в начале темы и были три варианта как поступить в таком случае. Может есть ещё какие-то подходы в таком случае. За это и интересуюсь.
0
|
||
|
1595 / 600 / 185
Регистрация: 05.12.2015
Сообщений: 970
|
|||||||
| 17.02.2019, 15:40 | |||||||
|
Какие тут могут быть "варианты"? Я предположил, что неясен вопрос как биндить свойства не имея информации о классе. Я ответил, что это не нужно и свойства биндиться по их именам и неважно в каком классе они находятся. То есть два разных класса
0
|
|||||||
|
|
|
| 17.02.2019, 16:05 | |
Сообщение было отмечено Элд Хасп как решение
Решение
Элд Хасп,
Во-первых. Насчет того может ли View знать о Model или нет. Ответ - может. Предназначение View - отображать модель. Она естественным образом зависит от модели. При изменении модели, View полюбому будет меняться. Во-вторых. Несмотря на то, что view может знать о модели, нужно уменьшать число связей между слоями приложения. Кроме того, у View и Model уже есть посредник в виде ViewModel. Если View будет обращаться то к модели, то к ViewModel - будет действительно нехорошо. В-треьтих. Как же решается эта проблема? Есть два подхода. Первый - так называемый "плоский вариант". Этот вариант подразумевает то, что View привязывается только к "простым" типам (string, int, float и т.д.) из ViewModel. Этот вариант подразумевает, что ViewModel будет дублировать все свойства объектов модели. Второй подход - это использование DTO объектов для передачи информации между View, ModelView и Model (особенно если Model - удаленная, находится на сервере, этот как раз ваш вариант, как я понял). DTO объекты не содержат логики и не являются частью модели. О DTO объектах могут знать все слои приложения. Эти объекты выносятся в отдельную dll которая используется как моделью, так и в View и ViewModel. При этом цепочка данных идет таким образом: Модель - вещь в себе, работает со своими доменными объектами как хочет, о внешнем коде ничего не знает. По запросу извне - модель отправляет данные в виде DTO. Сами доменные объекты не отправляются. Обновление данных в модели также происходит через отправку им DTO. Далее, ViewModel принимает DTO от модели и расшаривает DTO как свое свойство. View - биндится к DTO, расшаренному в ViewModel. Если пользователь меняет данные, то ViewModel отправляет DTO обратно в модель. Для нотификации о том, что свойства DTO поменялись - можно либо реализовать INotifyPropertyChanged у DTO, либо ViewModel может сравнить DTO полученный от сервера и текущий DTO, и если они различаются - отправлять измененный DTO обратно в модель.
1
|
|
| 17.02.2019, 16:05 | |
|
Помогаю со студенческими работами здесь
20
Model-View-Controller DefaultTreeModel - Model или View? Добавление полей структур в Model/View Qt Что такое Model - View - Controller Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
||||
|
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта
Симптом:
После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
|
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
|
Новый ноутбук
volvo 07.12.2025
Всем привет.
По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне:
Ryzen 5 7533HS
64 Gb DDR5
1Tb NVMe
16" Full HD Display
Win11 Pro
|
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
|
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
|
|
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов
На странице:
https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/
нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
|
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов.
. . .
|
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
|
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
|
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут.
В век Веб все очень привыкли к дизайну Single-Page-Application .
Быстренько разберем подход "на фреймах".
Мы делаем одну. . .
|