MVVM, где поставить общую логику - PullRequest
0 голосов
/ 27 июня 2018

У меня есть 3 экрана: главный экран со списком элементов, экран сведений об элементе и экран обновления элемента.

На главном экране отображается список элементов, каждый элемент в списке имеет две кнопки: «Обновить» и «Детали».

Если пользователь нажимает кнопку «Сведения», отображается экран сведений об элементе. На этом экране также есть кнопка «Обновить».

Обе кнопки «Обновить» работают по одной и той же (общей) логике:

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

Итак, поток:

Main (item list) screen -> Item details -> Item update
Main (item list) screen -> Item update

Количество моделей:

 class MainViewModel
 {
      readonly INavigationService _navigationService;
      readonly IDialogService _dialogService;

      public ICommand UpdateItemCommand { get; private set; }

      void ExecuteUpdateItem(Item item)
      {
           if(item.State == SomeState && otherLogic) 
           {
               _navigationService.NavigateTo("UpdateScreen");
           } else if(someLogic) {
               _navigationService.NavigateTo("OtherScreen");
           } else {
                // Show message to user
               _dialogService.ShowMessage(..);
           }
      }
 }

 class ItemDetailsViewModel
 {
      readonly INavigationService _navigationService;
      readonly IDialogService _dialogService;

      public ICommand UpdateItemCommand { get; private set; }

      void ExecuteUpdateItem(Item item)
      {
          // I don't want to duplicate code here
      }
 }

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

У меня есть одна идея - завести ребенка ItemViewModel:

 class ItemViewModel
 {
      readonly INavigationService _navigationService;
      readonly IDialogService _dialogService;

       public ICommand UpdateItemCommand { get; private set; }

      void ExecuteUpdateItem(Item item)
      {
           // put code here
      }
 }

 class MainViewModel
 {
      public IEnumerable<ItemViewModel> Items { get; private set; }
 }

 class ItemDetailsViewModel
 {
      public ItemViewModel Item { get; private set; }
 }

Есть ли лучший вариант? Могу ли я попросить модель выполнить обновление? Может ли моя модель инициировать навигацию между представлениями или отображать окно сообщения?

class Item
{
    public void UpdateItem(INavigationService navigationService, IDialogService dialogService) 
    {
          // Put code here...

    }
}

Или, может быть, ItemService, который делает это?

View-модели получают INavigationService и IDialogService путем внедрения зависимости. Если я добавлю ItemService, мне придется передать две службы из модели представления в службу ItemService.

...