ASP.NET MVC - 通过数据库动态填充表单

时间:2010-08-29 20:59:43

标签: c# asp.net-mvc asp.net-mvc-2

我正在将经典ASP中的搜索应用程序移植到ASP.NET MVC2。其中一个hte页面是一个动态填充的搜索表单,分为4个类别,每个类别有2行。

客户端可以取消选中每个类别的选项。发生这种情况时,每个类别都是从上到下,从左到右动态重新填充。编程Classic ASP版本的人设置了一个通过数据库搜索的子程序(每个搜索字段都有一个布尔字段),然后返回一个数组。然后他接受了数组并调用了另一个循环数组的子程序,然后生成了每个类别。

现在,我唯一能想到的是创建一个模型,其中包含每个类别的方法,每个类别都返回一个List。一个简单的例子是:

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>();

        // 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;
    }
}

然后我可以做的是根据每行的大小拆分列表,然后循环遍历每个列表并调用能够基于name参数动态呈现HTML的用户控件。

这种技术的问题在于,由于一些奇怪的原因,我觉得我不是以最简单的方式做这件事。对于读过这篇文章的人来说,有没有更简单的方法来实现它?

谢谢!

4 个答案:

答案 0 :(得分:1)

这是我一直想要调查的事情。在涉及到Rails之后,我被绑定到模型的视图所破坏了。

似乎MVC空间中有一个名为Html.EditorForModel()的帮助器。此帮助程序为视图绑定的模型生成表单。我不确定它会在你的情况下做什么,但看到输出肯定会很有趣,也许它可能会给你一些个人实现的想法。

祝你好运!

答案 1 :(得分:1)

这是我推荐的。创建包含动态内容的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");

}

这是ProductsController中的CategoryChanged函数

  [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;
  }
}

答案 2 :(得分:0)

如果需要,在客户端使用JavaScript(jQuery)添加列表怎么样?可以使用Ajax调用填充数据。一旦所有字段都已填入并且用户提交,则操作方法可以获取所有传入参数并基于此执行搜索。

答案 3 :(得分:0)

我建议使用内置的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 magic

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

jquery中的live方法将确保将操作附加到类的所有当前和未来实例(如果将其提供给局部视图中的所有复选框)。它们将导致ajax形式回发,然后返回部分视图 - 根据更新的模型重写,并替换div的内容。

这对纯客户端的好处是,你可以让MVC对你的模型做一些事情,而不必担心格式化或改变一堆javascript来改变任何外观或工作方式。您只需更改视图,一切都会自动运行。