ASP.NET MVC - динамическое заполнение формы через базу данных - PullRequest
8 голосов
/ 30 августа 2010

Я портирую поисковое приложение с Classic ASP на ASP.NET MVC2. Одна из страниц является динамически заполняемой формой поиска, которая разбита на 4 категории, каждая из которых состоит из 2 строк.

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

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

class SearchPageOrganizer {

    // Declare SearchFields object
    private SearchFields fields;

    // Contructor; instantiates SearchFields object
    public SearchPageOrganizer(SearchFields searchFields) {
       this.fields =  searchFields;
    }

    // Gets a list of fields active in the characteristics category
    public List<String> GetCharactersticsList() {
        List<String> list = new List<String&gt();

        // Check if the Color field is active
        if (fields.Color) {
            list.Add("Color");
        }

        // Check if the Size field is active
        if (fields.Size) {
            list.Add("Size");
        }

        // Return the list
        return list;
    }
}

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

Проблема с этой техникой заключается в том, что по какой-то странной причине мне кажется, что я делаю это не самым простым способом. Для тех, кто читает это, есть ли более простой способ реализовать это?

Спасибо!

Ответы [ 4 ]

1 голос
/ 16 ноября 2010

Это то, что я давно хотел исследовать. Покопавшись в Rails, я был испорчен привязкой вида к модели.

Похоже, что в пространстве MVC есть помощник Html.EditorForModel (). Этот помощник генерирует форму для модели, к которой привязано представление. Я не совсем уверен, что он будет делать в вашей ситуации, но, безусловно, было бы интересно посмотреть на результат, и, возможно, он может дать вам некоторые идеи для личной реализации.

Удачи!

1 голос
/ 18 ноября 2010

Вот что я бы порекомендовал. Создайте div, который содержит динамическое содержимое, и поместите его в частичное представление. В этом случае будет частичное представление с именем Products.ascx

 <div id="ProductsContent">
    <% Html.RenderPartial("Products"); %>
 </div>

Вызовите функцию javascript, когда установлен флажок категории.

<input id="Category_1" type="checkbox" onclick="CategoryCheckChanged(1)" />
<input id="Category_2" type="checkbox" onclick="CategoryCheckChanged(2)" />
<input id="Category_3" type="checkbox" onclick="CategoryCheckChanged(3)" />

используйте JQuery для определения значения флажка, а затем отправьте сообщение на сервер. В приведенном ниже примере имя моего контроллера называется Products. Информация, возвращаемая с сервера, является обновленным частичным представлением, которое заменяет содержимое div.

function CheckChanged(id) 
{
    var bChecked = $("#Category_"+id).attr("checked");

    var value = 0;
    if(bChecked) value=1;

     $.post('<%= Url.Action("CategoryChanged","Products") %>'
        , { value: value, categoryid: id }
        , function(data) {
           if (data.success) {
              alert("Sweet !")
              //update the div with the new content
              $('#ProductsContent').html(data.newcontent);
           }
           else {
              alert("Bummer:" + data.msg);
           }

        }, "json");

}

Вот функция CategoryChanged в ProductsController

  [HttpPost]
  public ActionResult CategoryChanged(int value, int id)
  {
     try
     {
        //Save the change to the database
        SaveChangedCategoryValueToDatabase(id,value);

        //Create your View Model
        MyProductsViewModel vm = new MyProductsViewModel();

        return Json(new { success = true, newcontent =
           MyViewHelper.RenderPartialToString(this.ControllerContext, 
           "~/Views/Products/Products.ascx", 
           new ViewDataDictionary(vm), new TempDataDictionary()) });

     }
     catch(SystemException ex)
     {
         return Json(new { success = false, msg = ex.Message });
     }

  }

и, наконец ... Вспомогательная функция, которая выполняет частичное представление строки.

public static class MyViewHelper
{
  public static string RenderPartialToString(ControllerContext context
     , string partialViewName
     , ViewDataDictionary viewData
     , TempDataDictionary tempData)
  {
     ViewEngineResult result = 
        ViewEngines.Engines.FindPartialView(context, partialViewName);

     if (result.View != null)
     {
        StringBuilder sb = new StringBuilder();
        using (StringWriter sw = new StringWriter(sb))
        {
           using (HtmlTextWriter output = new HtmlTextWriter(sw))
           {
              ViewContext viewContext = new ViewContext(
                 context, result.View, viewData, tempData, output);
              result.View.Render(viewContext, output);
           }
        }

        return sb.ToString();
     }

     return String.Empty;
  }
}
0 голосов
/ 22 ноября 2010

Я рекомендую использовать встроенные формы Ajax с MVC 2. У вас могут быть частичные элементы управления, которые строятся на основе переданной им модели. Ваш подход будет выглядеть примерно так:

Сначала контроллер

public PartialViewResult MySearchControl()
{
    //initialize the model

    return new PartialView(model)
}

[HttpPost]
public PartialViewResult MySearchControl(MyModel model)
{
    //do work, repopulate the model

    return new PartialView(model)
}

Тогда в представлении у вас будет что-то вроде этого.

<% using (Ajax.BeginForm("MySearchControl", "MySearch",
   new { },
   new AjaxOptions() { 
       HttpMethod = "Post",
       InsertionMode = InsertionMode.Replace,
       UpdateTargetId = "searchFormWrapper",
       OnSuccess = "doMoreWork"
        }, new { }))
{ %>

<div id="searchFormWrapper">
    <% Html.RenderAction<MySearchController>(x => x.MySearchControl()); %>
</div>

<input type="submit" id="mySubmitButton" value="submit" />

<% } %>

<script type="text/javascript">
    function doMoreWork()
    {
        // do anything needed after content is updated here
    }
</script>

Теперь, если вам нужен флажок для запуска отправки, вы можете использовать немного магии jquery

<script type="text/javascript">
    $(function () {
        $('.checkBoxClassSelector').live('change', new function(){
             $('#mySubmitButton').click();
        });
    });
</script>

Метод live в jquery обеспечит привязку действия ко всем текущим и будущим экземплярам класса, если вы установите его для всех флажков в частичном представлении. Они приведут к отправке обратно формы ajax, которая затем вернет ваше частичное представление - переписанное на основе обновленной модели и заменит содержимое div.

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

0 голосов
/ 03 сентября 2010

Как насчет добавления списков с использованием JavaScript (jQuery) на стороне клиента, когда это необходимо?Данные могут быть заполнены с помощью вызова Ajax.После заполнения всех полей и отправки пользователем метод действия может принять все входящие параметры и выполнить поиск на основе этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...