Структурирование сложных веб-форм в ASP.NET MVC

#asp.net-mvc

#asp.net-mvc

Вопрос:

Какой хороший подход в ASP.NET MVC для реализации сложной формы, где разделы формы отображаются и скрываются на основе вводимых пользователем данных?

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

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

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

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

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

Ответ №1:

Джош,

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

Что касается динамического изменения полей в вашем представлении, лучший способ — использовать jQuery (или любую другую библиотеку javascript) для этого.

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

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

После нескольких проектов с MVC, я на самом деле теперь нахожу, что для перехода и создания панелей обновления веб-форм требуется много времени 😉

Надеюсь, это поможет, -Covo

Ответ №2:

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

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

Ответ №3:

Традиционный asp.net webforms сделали для вас много «волшебства», в то время как вы должны быть осведомлены о работе, которая идет на создание «волшебства» в asp.net MVC. Преимущество заключается в том, что с MVC у вас больше контроля над происходящим, что также может повысить производительность.

В asp.net webforms панель обновления используется для вызовов ajax. Если вам нужно получить доступ к серверу асинхронно (без выполнения полной обратной публикации), тогда используйте ajax через jQuery. Смотрите, например, ниже:

             $.ajax({
                    type: "get",
                    url: "/YourController/YourAction",
                    success: function (obj) {
                       //any logic you want to do upon success
                    }
                });
  

В приведенном выше примере будет выполнен вызов ajax HTTP GET для /YourController /YourAction.

Чтобы справиться с «переключением блоков», если вам не нужно обращаться к серверу за данными, и вы просто хотите сделать это на клиенте, тогда используйте простой jquery. В jQuery есть функция для переключения элементов. http://api.jquery.com/toggle-event

Ответ №4:

Из-за того, как работает MVC в отличие от Webforms, на вас ложится ответственность за то, чтобы действительно думать о том, что происходит на клиенте, и о том, что происходит на сервере отдельно, поскольку не так много метаданных передается обратно, чтобы дать нам ощущение счастья от Webforms.

Однако при использовании встроенных библиотек AJAX при рендеринге формы существует представление о том, что она может автоматически обновляться после ее публикации. В некотором смысле, это избавляет вас от JavaScript / jQuery, потому что он «автоматически подключает» его аналогично панели. Таким образом, вы потенциально могли бы постепенно отображать свои сложные формы с сервера по мере редактирования каждого раздела и т.д.

Смотрите MSDN:http://msdn.microsoft.com/en-us/library/system.web.mvc.ajax.ajaxoptions.updatetargetid.aspx

Соответствующий пример кода, который даст вам представление (к сожалению, это не в более удобочитаемом синтаксисе Razor):

Соответствующей строкой является Ajax.BeginForm, где отображается тег form. Как только форма будет опубликована, библиотека MS AJAX автоматически обновит элемент, указанный в «UpdateTargetId», указанном в AjaxOptions формы. В этом случае ответ будет помещен в элемент SPAN «TextEntered» после получения ответа от сервера. Здесь вы могли бы постепенно предоставлять пользователю больше контента для заполнения, возможно, другую форму и т.д.

 <h2><%= Html.Encode(ViewData["Message"]) %></h2>
<p>
    Page Rendered: <%= DateTime.Now.ToLongTimeString() %>
</p>
<span id="status">No Status</span>
<br />   
<%= Ajax.ActionLink("Update Status", "GetStatus", new AjaxOptions{UpdateTargetId="status" }) %>
<br /><br />
<% using(Ajax.BeginForm("UpdateForm", new AjaxOptions{UpdateTargetId="textEntered"})) { %>
  <%= Html.TextBox("textBox1","Enter text")%>  
  <input type="submit" value="Submit"/><br />
  <span id="textEntered">Nothing Entered</span>
<% } %>