ViewModel держит модель? - PullRequest
3 голосов
/ 01 апреля 2011

На данный момент у меня есть следующая структура моего приложения:

  • Папка с именем ViewModels
  • Папка с именем Views
  • Папка с именем Services

В ViewModel есть класс ItemTypeDetailViewModel.Как это выглядит:

public class ItemTypeDetailViewModel
{
    private IItemTypenService itemTypeService;
    public ObservableCollection<Models.ItemType> ItemTypes { get; set; }
    public ICollectionView CollectionView { get; set; }

    public ItemTypeDetailViewModel()
    {
        itemTypeService = new ItemTypeService();
        itemTypeService.GetItemTypes();

        CollectionView = CollectionViewSource.GetDefaultView(ItemTypes);
    }
}

В классе у меня есть ссылка на служебный уровень (на данный момент нет DI, просто новые в конструкторе).С помощью itemTypeService я получу коллекцию ItemTypes.Возможно, это более структурированный вид MVP?

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

Что такое хорошийподходить сюда?

Ответы [ 2 ]

2 голосов
/ 01 апреля 2011

Но теперь я начинаю путаться, потому что в большинстве примеров MVVM, которые я вижу, модель обернута в ViewModel.

Какой здесь хороший подход?

Если каждый из ваших элементов данных (модель) является тривиальным, и то, как вы используете их в представлении, также тривиально, то нет никакой проблемы с отображением их «как есть» из ViewModel (создание дополнительной работы простопотому что это никогда не хорошая идея).С другой стороны, если вы обнаружите, что вам нужна функциональность, которую не так просто реализовать, это может указывать на то, что вам нужно обернуть каждую модель в ее собственную модель представления (ItemTypeViewModel).

Примеркогда вам может не понадобиться, ViewModel отображает элементы в списке только для чтения, и в этом случае вам будет хорошо использовать DataTemplate и ничего более.Контрпример будет, если вам нужно отредактировать их, и изменения должны быть проверены;Затем ViewModel будет содержать логику проверки.

Подводя итог: не сходите с ума с MVVM, если для этого нет причин.Будьте практичны.

Последнее замечание о том, что ViewModel имеет доступ к представлению:

В этом нет проблем, если вы не используете открытый интерфейс среды выполнения представления.type. Фактически, MVMM-first-ViewModel требует , чтобы ViewModel имела ссылку на View.Многие люди скажут вам, что это автоматическая ошибка - они ошибочны , и, вероятно, под влиянием того факта, что View-first (разновидность MVVM, встречающаяся в большинстве примеров) не имеет ViewModelссылка на представление.

Если для представления все в порядке, если ссылка имеет вид ViewModel в качестве DataContext, то также можно использовать и обратное.Важным моментом является то, как используется эта ссылка: public object View { get; set; }, конечно, хорошо , потому что она не вводит никакой связи ;но public MyUserControl View { get; set; } нет, потому что он связывает ViewModel с конкретным типом MyUserControl.

2 голосов
/ 01 апреля 2011

(Первая часть из моего комментария выше: представление должно привязываться к ViewModel. ViewModel не может ничего знать о потенциальных представлениях. Вы можете написать новое представление для работы с существующей ViewModel - или вы можете написать модульные тесты для вашей ViewModelи поэтому представление, упомянутое во ViewModel, неуместно.)

Я не совсем уверен, что именно вы пытаетесь сделать, но это похоже на подробное представление для ItemType.Я не понимаю, почему тогда у вас ВСЕ типы элементов запрашиваются внутри конструктора?

Я бы сделал что-то вроде этого:

  • Создайте ItemTypesViewModel, который имеетколлекция ItemTypeDetailViewModel, с отложенной загрузкой
  • Создайте где-нибудь хранилище, которое ViewModels будет использовать для запроса модели (данных) (например, IItemTypeService делает это, я думаю)

Быстрый пример без отложенной загрузки:

    public class ItemTypesViewModel : ViewModelBase
    {
        private List<ItemTypeDetailViewModel> itemTypeViewModels;

        public IEnumerable<ItemTypeDetailViewModel> ItemTypes
        {
            get
            {
                return itemTypeViewModels;
            }
        }

        public ItemTypesViewModel(IItemTypeService service)
        {
            // populate itemTypeViewModels using service here
        }
    }

Обновление, более актуально Я думаю / надеюсь: То, что я обычно делаю с точки зрения доступа к уровню обслуживания, этостатический член в классе ViewModel, который действует как память фабрики.Пример:

public class ItemTypesViewModel : ViewModelBase
{
    public static ItemTypesViewModel Create(IItemTypeService service)
    {
        // build and return object here
    }
}

В какой-то момент вы должны пересечь границы, и этот метод на мой личный вкус ... было бы интересно посмотреть, что делают другие.Возможно, дополнительный слой или набор фабрик для ViewModels.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...