ASP.NET MVC — Сложная логика представления

#asp.net-mvc

#asp.net-mvc

Вопрос:

Я совершаю переход с webforms на MVC (я знаю, с опозданием на 3 года), и по большей части я «понимаю», но есть несколько вещей, по которым я хотел бы получить совет и разъяснения:

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

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

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

Я знаю, что привязка данных является возможным решением, но мне не нравится отказываться от контроля.

Наконец, вернемся к концепции «страниц с отслеживанием состояния» — скажем, у меня есть страница панели мониторинга, на которой есть календарь (я написал свой собственный класс управления календарем, сам элемент управления не имеет состояния, но может использовать webform viewstate для хранения информации о подкачке) — как пользователь может просматривать страницы по календарным месяцам? Очевидно, что POST неуместен, поэтому он должен быть с GET с параметром querystring — как я могу это сделать в MVC? (не говорите AJAX).

Спасибо!

Ответ №1:

В MVC вы разрабатываете свои действия в соответствии с вашими потребностями. Например, если вы хотите иметь возможность добавлять 5 строк в счет-фактуру, НЕ используя сценарии на стороне клиента, вам, вероятно, потребуется, чтобы ваше действие GET для генерации счета-фактуры принимало обнуляемый параметр int для количества строк. Сохраните текущее количество строк в модели представления для страницы и создайте на странице ссылку на ваше действие GET, значение параметра которого на 5 больше текущего значения. Пользователь нажимает на ссылку, и GET view генерирует страницу с запрошенным количеством строк.

Контроллер

  [HttpGet]
 public ActionResult Invoice( int? rows )
 {
      rows = rows ?? 5; // probably you'd pull the default from a configuration
      ...

      viewModel.CurrentRows = rows;
      return View( viewModel );
 }
  

Вид

  @Html.ActionLink( "Add 5 Lines", "invoice", new { rows = Model.CurrentRows   5 }, new { @class = "add-rows" } )
  

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

  <script type="text/javascript">
      $(function() {
          $('.add-rows').click( function() {
                ...add additional inputs to the invoice...
                return false; // abort the request
          });
      });
 </script>
  

Аналогично для вашего календаря. Общая идея заключается в том, что вы помещаете в свою модель представления достаточно информации, чтобы генерировать все действия, которые вы хотите выполнить из своего представления. Создайте ссылки или формы (да, у вас может быть несколько форм!) В своем представлении, чтобы выполнить действие. Используйте параметры для передачи контроллеру / действию того, что нужно сделать. В редких случаях, когда вам необходимо сохранять состояние между действиями, скажем, при выполнении мастера, который выполняет несколько действий, вы можете сохранить информацию в сеансе или использовать TempData (который использует сеанс).

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

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

Комментарии:

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

2. @David — здесь есть фундаментальное дизайнерское решение. Я бы, вероятно, выбрал простое решение, предполагающее, что у пользователя включен JS, и сделал бы это так, как я описал. Пользователь, у которого не включен JS, будет иметь ухудшенный интерфейс, но он может получить улучшенный интерфейс, просто включив JS, так что это действительно его выбор. В противном случае у вас есть более сложное решение, которое принимает ваше действие POST в ответ на нажатие кнопки отправки «Добавить 5 строк» — дайте ему имя, и оно отправит сообщение обратно в качестве параметра, который вы можете обнаружить, и попросите его восстановить представление с данными и дополнительными строками.

Ответ №2:

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

Ответ №3:

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

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

я не уверен, что у вас с ajax или javascript

Комментарии:

1. Если пользователь делает СООБЩЕНИЕ на странице, на которой были входные данные, сгенерированные итерацией, как контроллер считывает эту информацию? Как я могу выполнить проверку тоже? Ta!

2. проверка модели встроена в структуру: asp.net/mvc/mvc3#BM_Model_Validation_Improvements . контроллер принимает список элементов в качестве одного из своих параметров, а связующее средство модели mvc отвечает за то, чтобы отправленные данные были преобразованы в соответствующий тип списка и переданы в контроллер

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

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