使用jQuery和MVC进行客户端-服务器搜索

Client-server searching with jQuery and MVC

本文关键字:客户端 服务器 搜索 jQuery MVC 使用      更新时间:2023-09-26

我有一个带有两个下拉列表的视图,用于搜索描述。结果列表现在显示在另一个视图中。我希望在相同的搜索视图中生成结果。我认为一些AJAXJquery可以用来解决这个问题,但不知道如何解决。那么,在这种情况下,如何在同一个视图页面中显示搜索结果呢?

此外,我对Search controller有一些疑问。我希望至少选择一个下拉列表(两个下拉列表都不应为空)。如何验证该部分?

查看

@using (Html.BeginForm("Search","Work",FormMethod.Get))
{
    <fieldset>
        <legend>Search</legend>
    <div class="editor-label">
            @Html.LabelFor(model => model.JobTypeID, "Job Type")
        </div>
        <div class="editor-field">
            @Html.DropDownList("JobTypeID", "Select Job Type")
        </div>
        <div class="editor-label">
            @Html.LabelFor(model => model.JobPriorityID, "Job Priority")
        </div>
        <div class="editor-field">
            @Html.DropDownList("JobPriorityID", "Select Job Priority")
        </div>
         <p>
            <input type="submit" value="Search" />
        </p>
        </fieldset>
}

控制器:

 [HttpGet]
        public ActionResult Search(int? jobtypeid, int? jobpriorityid)
        {
            var vJobDescriptions = new List<JobDescription>();
            if (jobtypeid != null && jobpriorityid != null )
            {
                 vJobDescriptions = (from description in db.JobDescriptions
                                        where (description.JobTypeID == jobtypeid && description.JobPriorityID == jobpriorityid)
                                        select description).ToList();
            }
            else if (jobtypeid == null && jobpriorityid != null)
            {
                 vJobDescriptions = (from description in db.JobDescriptions
                                        where (description.JobPriorityID == jobpriorityid)
                                        select description).ToList();
            }
            else if (jobtypeid != null && jobpriorityid == null)
            {
                vJobDescriptions = (from description in db.JobDescriptions
                                    where (description.JobTypeID == jobtypeid)
                                    select description).ToList();
            }
            else
            {
                vJobDescriptions = (from description in db.JobDescriptions
                                    select description).ToList();
            }

            return View(vJobDescriptions);
        }

一种可能性是使用Ajax.BeginForm而不是普通形式(不要忘记在页面中包含jquery.jsjquery.unobtrusive-ajax.js脚本):

@using (Ajax.BeginForm("Search", "Work", new AjaxOptions { UpdateTargetId = "results" }))

那么您可以为我们在UpdateTargetId:中指定的结果设置一个占位符

<div id="results"></div>

现在剩下的就是让您的搜索控制器操作返回一个PartialView,并将包含搜索结果的模型传递给它:

public ActionResult Search(int? jobtypeid, int? jobpriorityid)
{
    var model = ...
    return PartialView("_Result", model);
}

当然还有相应的_Result.cshtml部分:

@model IEnumerable<MyViewModel>
...

此外,我对搜索控制器有一些疑问。我至少要一个要选择的下拉列表(两个下拉列表都不应该允许为null)。如何验证该部分?

我建议您使用FluentValidation.NET,但如果您不想使用第三方库,您可以编写一个自定义验证属性来执行此验证,然后用它装饰绑定到下拉列表的两个视图模型属性之一。

不幸的是,如果您决定采用AJAX方法,则必须能够显示来自服务器的验证错误,以防出现问题。所以它是整个形式,必须放在分部里面。

您可以使用的另一种方法是使用不带AJAX的标准表单简单地重新加载整个页面。结果将作为集合属性作为初始视图模型的一部分,该集合属性最初为null,执行搜索后,您将用结果填充它。然后在视图中,您将测试属性是否不为null,以及是否不包括负责呈现结果的Partial:

@using (Html.BeginForm("Search", "Work", FormMethod.Get))
{
    ...
}
<div id="results">
    @if (Model.Results != null)
    {
        @Html.Partial("_Results", Model.Results)
    }
</div>

实现这一点的基本方法是将搜索结果的标记放在局部视图中,并从Search ActionMethod返回。这将需要您将搜索方法的最后一行更改为

return Partial(vJobDescriptions)

在您的客户端脚本中,您将执行以下操作:

var data = $("form").serialize();
$.get("/Search", data)
 .complete(function(results) { 
     $("form").replace(results) };

关于您正在寻找的验证方面,我会考虑将您的读取模型与搜索命令参数分离。

public ActionResult Search(SearchModel search)
{
     if (!ModelState.IsValid) // return view w/ invalid model
}

你的搜索参数模型将沿着以下几条线:

[CustomValidation(typeof(SearchModel), 
                  "OneNotNullValidator", 
                  "One option must be selected"]
public class SearchModel 
{
     public int? JobTypeID { get; set;}
     public int? JobPriorityID { get; set;}
     public bool OneNotNullValidator()
     {
          return JobTypeID.HasValue || JobPriorityID.HasValue;
     }
}

我应用于类的CustomValidation属性在特定的语法和名称上可能不是100%正确的,但我希望它的要点能被理解。