Подтвердить что ты не робот

MVVM: должен ли объект VM публиковать объект M напрямую или только через геттеры, делегирующие M-геттерам?

лучший способ объяснить - это пример:

это модель

public class Person 
{
    public int age;
    public string name;
}

это модель представления

public class PersonVM
{    
}

мой вопрос:
должен ли vm подвергать человека шаблону данных или инкапсулировать свойства модели своими собственными свойствами?

4b9b3361

Ответ 1

Модель просмотра должна объявить свои собственные свойства и скрыть специфику модели из представления. Это дает вам максимальную гибкость и помогает не допустить, чтобы типы типов моделей не попадали в классы моделей. Обычно классы модели представления инкапсулируют модель путем делегирования. Например,

class PersonModel {
    public string Name { get; set; }
}

class PersonViewModel {
    private PersonModel Person { get; set;}
    public string Name { get { return this.Person.Name; } }
    public bool IsSelected { get; set; } // example of state exposed by view model

    public PersonViewModel(PersonModel person) {
        this.Person = person;
    }
}

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

Ответ 2

Нет общего соглашения по этому вопросу. Например, это был один из открытых вопросов о MVVM, сформулированный Ward Bell здесь:

Разрешено ли виртуальной машине V развернутый M-объект (например, необработанный Наемный рабочий)? Или должны M-объекты свойства (если даже разрешено есть свойства!) исключительно через поверхность Обертка VM?

Основными преимуществами прямого воздействия на модель в VM являются:

  • вы можете использовать его как "конвертер на стероидах", формируя значения модели удобным образом для представления

  • вы можете добавить другую функциональность, связанную с пользовательским интерфейсом, например сообщения о проверке данных, отменить повтор,..

Концы:

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

  • если вы привяжете элемент управления view к свойству viewmodels, вы отправите события propertyChanged из viewmodel. Но что произойдет, если свойство модели изменится с другого источника, отличного от setmodel setter? Затем он должен уведомить viewmodel, чтобы вы закончили с 2 OnPropertyChanged, один в модели и один в viewmodel... довольно сложный!

Итак, для меня правильный ответ: это зависит от ваших требований.

Ответ 3

Наличие ViewModel для любой модели может быть хуже. Что делать, если у вас есть иерархическая структура модели или даже простая коллекция? В этом случае вам придется перебирать все модели и создавать экземпляр ViewModel для каждой модели, а также регистрировать события изменения уведомлений или другие события. ИМХО, это совершенно безумное и необоснованное. Как сказал DaniCE, у вас будет много кода и большая головная боль.

Ответ 4

Интересное решение для этого было предложено Робертом МакКартером в томе 25 MSDN.

http://msdn.microsoft.com/en-us/magazine/ff798279.aspx

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

Если ваше проблемное пространство не требует высокой производительности (динамика наносит удар производительности), это отличное решение. View не должен ничего знать о модели, но Model View не имеет свойств прокси, которые предоставляются "как есть". В любое время свойства могут быть добавлены в модель просмотра для обертывания свойств модели без изменения вида или модели. Прочтите статью для более подробной информации.