Подход к графическому интерфейсу компонента MVC

Меня интересует общий подход к созданию интерактивного графического интерфейса с использованием MVC3.

Идея состоит в том, чтобы создать набор различных компонентов, которые можно интегрировать (подключать) в различные сценарии.

Каждый компонент ДОЛЖЕН иметь собственное определение модели, контроллер и представления. Компонент инкапсулирует не только представление, но и поведение через свой контроллер.

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

Контекст, в котором выполняется компонент, не должен делать никаких предположений о внутренних деталях реализации компонента.

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

Наконец, компонент должен предоставлять механизм для «общения» или «взаимодействия» с внешним миром. Помимо внутренних компонентов, компонент должен предоставлять какой-то «внешний» интерфейс (например, параметры, данные, функции, события и т. д.), который позволил бы интегрировать компонент в контекст выполнения.

Контекст (или сценарий) — это часть, содержащая компоненты. Теперь основной задачей контекста является управление взаимодействием между компонентами.

Пример из реальной жизни компонента "Категории":

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

Реальный пример компонента Products:

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

Реальный пример страницы информационной панели (контекст, сценарий):

На странице отображаются компоненты «Категории» и «Продукты». Компонент «Продукты» отображает все продукты для текущей выбранной категории и, следовательно, должен предоставлять внешний интерфейс (параметр или что-то еще) для получения идентификатора выбранной категории из контекста. Компонент категорий должен предоставлять какой-либо внешний интерфейс, чтобы контекст мог действовать при изменении выбранной категории и предоставлять идентификатор выбранной категории для компонента продуктов.

Технически коммуникационный подход для обновления страниц в основном будет проходить через AJAX, но если это возможно без AJAX, это было бы даже лучше.

В случае с AJAX мне хотелось бы решение, в котором используются контроллеры на стороне сервера, которые решают и отображают то, что должно быть обновлено на клиенте (JSON или что-то в этом роде).

Мне бы не понравилось решение в клиентском скрипте (контроллер типа "как" на стороне клиента), который решает, какие действия вызывать и какие части страницы обновлять - это, как сказано в предыдущем абзаце, должно решаться контроллером ( с) на сервере.

Важно: Компоненты не обязательно должны работать при прямом вызове через какой-либо маршрут.

Как бы вы вообще реализовали описанную систему?


person Dusan    schedule 24.03.2012    source источник
comment
У меня большой опыт создания сложных систем с использованием описанных подобных компонентов с использованием классических веб-форм ASP.Net. Однако я не вижу, как такой подход можно реализовать в MVC. MVC обеспечивает большую гибкость и повторное использование отображения (отображение HTML), но полностью забывает о поведении — компонент — это не только внешний вид, но и то, что компонент делает и позволяет вам делать (поведение). В MVC я знаю, как повторно использовать представления (сделать их модульными), но я действительно не понимаю, как можно создать повторно используемое поведение (теперь, всякий раз, когда я использую компонент, я получаю дублированный код).   -  person Dusan    schedule 23.05.2012


Ответы (3)


Каждый контроллер обрабатывает весь шаблон пользователь-машина. То есть, грубо говоря, каждый контроллер отвечает за организацию взаимодействия пользователя с машиной для случая пользователя (шаблоны пользователя и машины, которые являются результатом фазы анализа). Теперь, если вы поместите «стандартное поведение» в контроллеры, кто будет координировать шаблон взаимодействия пользователя с машиной? Таким образом, у вас будут «компоненты» без чего-то, что координировало бы их выполнение. В веб-формах у вас есть страницы, которые координируют выполнение компонентов, помещенных в них... но в Mvc эту координирующую роль играют сами контроллеры.

Вы можете создавать черные ящики, состоящие из контроллеров и представлений, только если каждый из них отвечает за весь шаблон взаимодействия пользователя с машиной. Это «большие компоненты», а не маленькие строительные блоки, как в случае внедрения CMS.

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

person Francesco Abbruzzese    schedule 28.05.2012
comment
Я хочу сосредоточить программирование на логике, когда компоненты используются в каком-то сценарии (варианте использования). Почему мне приходится заново реализовывать все СТАНДАРТНЫЕ поведения и логику взаимодействия каждый раз, когда я использую компонент? Возьмем, к примеру, Grid с возможностями фильтрации-сортировки-постраничного выбора. Почему я должен заново изобретать модель, которая описывает ВНУТРЕННЕЕ состояние сетки и ВНУТРЕННЮЮ логику, которая выполняет операции с моделью (делает сетку интерактивной, имеет поведение) каждый раз, когда я помещаю сетку в какой-то контекст (вариант использования)?? ? В случае использования меня интересует только текущий выбор, а не внутренности - как это сделать? - person Dusan; 29.05.2012
comment
Я понимаю вашу проблему. Давайте поговорим о сетке, чтобы быть более конкретным. Часто логика для обработки сетки перемещается в контроллер. Это НЕПРАВИЛЬНО, сетка является компонентом пользовательского интерфейса, поэтому я могу быть реализован как компонент, однако без включения контроллера внутри него. Он должен получить на вход страницу данных в виде списка объектов и вернуть контроллеру: 1) выбрана новая страница 2) новые критерии регистрации (как выражение linq) 3) новые критерии сортировки 4) изменения, примененные к данным. Мы можем внедрить все это как компонент... без включения в него контроллера. Взгляните на мой инструментарий Mvc Controls Toolkit. - person Francesco Abbruzzese; 29.05.2012

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

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

Kigg
http://www.nopcommerce.com/downloads.aspx
http://orchard.codeplex.com/

Мне сложно сказать, как это должно быть реализовано. Лучше закодировать. Но использование Dependecy Injection of Views, Controllers, Services и Repositories обязательно в вашем случае.

person Alexandr    schedule 23.05.2012

Мне кажется, что вы пытаетесь достичь чего-то, что может быть несовместимо с философией web MVC (другие реализации MVC могут это поддерживать).

Однако, если бы вы захотели написать фреймворк поверх ASP MVC, я уверен, вы могли бы добиться того, чего хотите. Например, используя Areas, вы можете достичь формы инкапсуляции ваших контроллеров, моделей представлений и представлений.

Чтобы составить разные области для одного и того же главного представления, вы можете написать эквивалент фронт-контроллера с собственным представлением, которое принимает модель представления — эта модель представления будет подготовлена ​​фронт-контроллером для рендеринга действий из разных областей.

Вы можете добиться большего, используя клиентскую структуру, такую ​​как Backbone.js, поверх ASP MVC.

person Rob Kent    schedule 28.05.2012