Лучшие практики ViewModel

Ну, я обнаружил, что проблема заключалась в том, что я копировал исходное содержимое таким образом, чтобы не делать фактическое копирование содержимого, а делать ссылки. Поэтому я исправил проблему, скопировав содержимое элемента в новый экземпляр itemModel. После этого diff util способен дифференцировать должным образом.

Вместо этого,

private fun updateItem(item: ItemModel, status: Status) {
       ......................................................


            for ((index, el) in currentItems.withIndex()) {
                if (el.id == item.id) {
                    val currentItem = currentItems.removeAt(index)

                    currentItem.status = status
                    currentItems.add(index, currentItem)
                    break
                }
            }
            itemModels.value = currentItems
          ......................................
    }

Я сделал это,

private fun updateItem(item: ItemModel, status: Status) {
...............
    if (el.id == item.id) {
         currentItems.removeAt(index)
         val currentItem = ItemModel(item.id, "${item.title}, ${status.progress}")
         currentItem.status = status
         currentItems.add(index, currentItem)
         break
     }
...........
}
234
задан Community 23 May 2017 в 02:10
поделиться

10 ответов

Я создаю то, что я называю "ViewModel" для каждого представления. Я поместил их в папку под названием ViewModels в моем веб-проекте MVC. Я называю их в честь контроллера и действия (или представление), они представляют. Таким образом, если я должен передать данные представлению SignUp о контроллере Членства, я создаю класс MembershipSignUpViewModel.cs и помещаю его в папку ViewModels.

Затем я добавляю необходимые свойства и методы для упрощения передачи данных от контроллера до представления. Я использую Автокартопостроитель для получения от моего ViewModel до Модели предметной области и назад снова при необходимости.

Это также работает хорошо на составные ViewModels, которые содержат свойства, которые имеют тип другого ViewModels. Например, если у Вас есть 5 виджетов на индексной странице в контроллере членства, и Вы создали ViewModel для каждого частичного представления - как Вы передаете данные от Индексного действия до partials? Вы добавляете свойство к MembershipIndexViewModel типа MyPartialViewModel и при рендеринге частичного, которое Вы передали бы в Модели. MyPartialViewModel.

При выполнении его этот путь позволяет Вам корректировать частичные свойства ViewModel, не имея необходимость изменять представление Index вообще. Это все еще просто передает в Модели. MyPartialViewModel, таким образом, существует меньше шанса, что необходимо будет пройти целую цепочку partials для фиксации чего-то, когда все Вы делаете, добавляет свойство к частичному ViewModel.

Я также добавлю пространство имен "MyProject. Сеть. ViewModels" к web.config, чтобы позволить мне ссылаться на них в любом представлении, никогда не добавляя явного оператора импорта на каждом представлении. Просто делает его немного более чистым.

208
ответ дан DOK 23 November 2019 в 03:29
поделиться

Класс ViewModel там для инкапсуляции нескольких частей данных, представленных экземплярами классов в одно легкое для управления объектом, который можно передать Представлению.

имело бы смысл иметь Ваши классы ViewModel в их собственных файлах в собственном каталоге. В моих проектах у меня есть подпапка папки Models под названием ViewModels. Это - то, где мои ViewModels (например, ProductViewModel.cs) живут.

14
ответ дан JMS 23 November 2019 в 03:29
поделиться

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

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

4
ответ дан Preet Sangha 23 November 2019 в 03:29
поделиться

Я сохраняю свои классы приложений в sub папке под названием "Ядро" (или отдельная библиотека классов) и использую те же методы в качестве примера приложения KIGG, но с некоторыми небольшими изменениями для подавания моих заявок больше DRY.

Я создаю класс BaseViewData в/Core/ViewData/, где я храню общий сайт широкие свойства.

После этого я также создаю все свои классы представления ViewData в той же папке, которые затем происходят из BaseViewData и имеют представление определенные свойства.

Затем я создаю ApplicationController, из которого происходят все мои контроллеры. ApplicationController имеет универсальный Метод GetViewData следующим образом:

protected T GetViewData<T>() where T : BaseViewData, new()
    {
        var viewData = new T
        {
           Property1 = "value1",
           Property2 = this.Method() // in the ApplicationController
        };
        return viewData;
    }

Наконец, в моем действии Контроллера я делаю следующее для создания моей Модели ViewData

public ActionResult Index(int? id)
    {
        var viewData = this.GetViewData<PageViewData>();
        viewData.Page = this.DataContext.getPage(id); // ApplicationController
        ViewData.Model = viewData;
        return View();
    }

Я думаю, что это работает действительно хорошо, и это сохраняет Ваши представления опрятными и Ваши контроллеры тощий.

21
ответ дан Mark 23 November 2019 в 03:29
поделиться

Нет никакого хорошего места для удержания моделей. Можно сохранить их в отдельном блоке, если проект является большим и существует много ViewModels (Объекты Передачи данных). Также можно сохранить их в отдельной папке проекта сайта. Например, в Oxite они размещаются в проект Oxite, который содержит много различных классов также. Контроллеры в Oxite перемещены для разделения проекта, и представления находятся в отдельном проекте также.
В CodeCampServer ViewModels названы *Форма, и они размещаются в проект UI в папке Models.
В проекте MvcPress они размещаются в проект Данных, который также содержит весь код для работы с базой данных и немного больше (но я не рекомендовал этот подход, это только для образца),
Таким образом, Вы видите, что существуют многие точка зрения. Я обычно сохраняю свой ViewModels (объекты DTO) в проекте сайта. Но когда у меня есть больше чем 10 моделей, я предпочитаю перемещать их для разделения блока. Обычно в этом случае я перемещаю контроллеры для разделения блока также.
Другой вопрос состоит в том, как легко отобразить все данные от модели до Вашего ViewModel. Я предлагаю взглянуть на библиотеку AutoMapper. Мне нравится он очень, это делает всю грязную работу для меня.
И я также я предлагаю посмотреть на проект SharpArchitecture. Это обеспечивает очень хорошую архитектуру для проектов, и это содержит много прохладных платформ и руководств и великого сообщества.

12
ответ дан zihotki 23 November 2019 в 03:29
поделиться

В нашем случае у нас есть модели вместе с контроллерами в проекте отдельно от представлений.

Как правило, мы пытались перемещать и избегать большей части ViewData. ["..."] в ViewModel, таким образом, мы избегаем приведений и магических строк, что хорошо.

ViewModel также содержит некоторые общие свойства, такие как информация о разбиении на страницы для списков или информация заголовка страницы для рисования хлебных крошек и титулы. На данный момент базовый класс содержит слишком много информации, на мой взгляд, и мы можем разделить его на три части: самая основная и необходимая информация для 99% страниц в модели базового представления, а затем модель для списков и модель. для форм, которые содержат определенные данные для этих сценариев и наследуются от базового.

Наконец,

2
ответ дан 23 November 2019 в 03:29
поделиться

Мы помещаем все наши ViewModels в папку Models (вся наша бизнес-логика находится в отдельном проекте ServiceLayer)

5
ответ дан 23 November 2019 в 03:29
поделиться

Разделение классов по категориям (контроллеры, модели представления, фильтры и т. Д.) - это ерунда.

Если вы хотите написать код для раздела «Домашняя страница» своего веб-сайта (/), создайте папку с именем Home и поместите туда HomeController, IndexViewModel, AboutViewModel и т. Д. И все связанные классы, используемые действиями Home.

Если у вас есть общие классы, такие как ApplicationController, вы можете поместить его в корень вашего проекта.

Зачем разделять связанные вещи (HomeController, IndexViewModel) и хранить вместе вещи, которые вообще не имеют отношения (HomeController, AccountController)?


Я написал сообщение в блоге по этой теме.

122
ответ дан 23 November 2019 в 03:29
поделиться

код в контроллере:

    [HttpGet]
        public ActionResult EntryEdit(int? entryId)
        {
            ViewData["BodyClass"] = "page-entryEdit";
            EntryEditViewModel viewMode = new EntryEditViewModel(entryId);
            return View(viewMode);
        }

    [HttpPost]
    public ActionResult EntryEdit(Entry entry)
    {
        ViewData["BodyClass"] = "page-entryEdit";            

        #region save

        if (ModelState.IsValid)
        {
            if (EntryManager.Update(entry) == 1)
            {
                return RedirectToAction("EntryEditSuccess", "Dictionary");
            }
            else
            {
                return RedirectToAction("EntryEditFailed", "Dictionary");
            }
        }
        else
        {
            EntryEditViewModel viewModel = new EntryEditViewModel(entry);
            return View(viewModel);
        }

        #endregion
    }

код в виду модели:

public class EntryEditViewModel
    {
        #region Private Variables for Properties

        private Entry _entry = new Entry();
        private StatusList _statusList = new StatusList();        

        #endregion

        #region Public Properties

        public Entry Entry
        {
            get { return _entry; }
            set { _entry = value; }
        }

        public StatusList StatusList
        {
            get { return _statusList; }
        }

        #endregion

        #region constructor(s)

        /// <summary>
        /// for Get action
        /// </summary>
        /// <param name="entryId"></param>
        public EntryEditViewModel(int? entryId)
        {
            this.Entry = EntryManager.GetDetail(entryId.Value);                 
        }

        /// <summary>
        /// for Post action
        /// </summary>
        /// <param name="entry"></param>
        public EntryEditViewModel(Entry entry)
        {
            this.Entry = entry;
        }

        #endregion       
    }

проекты:

  • DevJet.Web (ASP.NET MVC web). проект)

  • DevJet.Web.App.Словарь ( a Отдельный проект Библиотеки классов)

    в этом проекте я сделал несколько папок типа: DAL, БЛЛ, БО, VM (папка для просмотра моделей)

0
ответ дан 23 November 2019 в 03:29
поделиться

вот фрагмент кода из моих лучших практик:

    public class UserController : Controller
    {
        private readonly IUserService userService;
        private readonly IBuilder<User, UserCreateInput> createBuilder;
        private readonly IBuilder<User, UserEditInput> editBuilder;

        public UserController(IUserService userService, IBuilder<User, UserCreateInput> createBuilder, IBuilder<User, UserEditInput> editBuilder)
        {
            this.userService = userService;
            this.editBuilder = editBuilder;
            this.createBuilder = createBuilder;
        }

        public ActionResult Index(int? page)
        {
            return View(userService.GetPage(page ?? 1, 5));
        }

        public ActionResult Create()
        {
            return View(createBuilder.BuildInput(new User()));
        }

        [HttpPost]
        public ActionResult Create(UserCreateInput input)
        {
            if (input.Roles == null) ModelState.AddModelError("roles", "selectati macar un rol");

            if (!ModelState.IsValid)
                return View(createBuilder.RebuildInput(input));

            userService.Create(createBuilder.BuilEntity(input));
            return RedirectToAction("Index");
        }

        public ActionResult Edit(long id)
        {
            return View(editBuilder.BuildInput(userService.GetFull(id)));
        }

        [HttpPost]
        public ActionResult Edit(UserEditInput input)
        {           
            if (!ModelState.IsValid)
                return View(editBuilder.RebuildInput(input));

            userService.Save(editBuilder.BuilEntity(input));
            return RedirectToAction("Index");
        }
}
6
ответ дан 23 November 2019 в 03:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: