且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在Layout.cshtml中设计MVC5全局搜索功能

更新时间:2023-02-24 21:45:18

这听起来像是这是AJAX的基本示例,因此用户无需重新加载页面即可查看结果.

This is a basic example with AJAX so the user will see results without a page reload.

_Layout.cshtml

<div class="header">
    @Html.Action("SearchWidget", "GlobalSearch")
</div>

@RenderBody()

<script src="jquery.js" />
<script>
    $(".global-search-form").on("click", "button", function(e)
    {
        $.ajax({
            url: "/GlobalSearch/Search",
            method: "GET",
            data: { item: $("input[name='item']").val() }
        })
        .then(function(result)
        {
            $(".global-search-result").html(result);
        });
    });
</script>

_Search.cshtml

<div class="global-search-widget">
    <div class="globa-search-form">
        <label for="item">Search For:</label>
        <input type="text" name="item" value="" />
        <button type="button">Search</button>
    </div>
    <div class="global-search-results"></div>
</div>

_SearchResults.cshtml

@model MyNamespace.SearchResults

<div>Results</div>
<ul>
@foreach(var item in Model.Suggestions)
{
    <li>@item</li>
}
</ul>

搜索结果

public class SearchResults
{
    public List<string> Suggestions { get; set; }
}

GlobalSearchController

[HttpGet]
[ChildActionOnly]
public ActionResult SearchWidget()
{
    return PartialView("_Search");
}

[HttpGet]
public ActionResult Search(string item)
{
    SearchResults results = searchService.Find(item);
    return PartialView("_SearchResults", results);
}

我们将@model声明保留在布局"页面之外,并将其移至子动作的局部视图.此示例将搜索窗口小部件加载到Layout中,但是您可以在所需的任何视图上使用它.

We keep the @model declaration out of the Layout page and move it to the Child Action's partial view. This example loaded the search widget into Layout but you can use it on any view you want.

为使操作简单,AJAX由按钮触发,但您可以对其进行修改以在延迟的文本更改时触发.结果也可能是JSON而不是局部视图-一些客户端的Type-Ahead插件可能会将结果作为JSON处理.

To keep things simple here, the AJAX is triggered by a button but you can modify it to trigger on a delayed text change. The result could also be JSON instead of a parital view -- some client-side Type-Ahead plug-ins may handle the results as JSON.

您可以删除所有脚本并将小部件转换为适当的格式.

You can drop all the script and convert your widget to a proper form.

@model MyNamespace.SearchForm

@using(Html.BeginForm("Search", "GlobalSearch", FormMethod.Get, new { item = ViewBag.GlobalSearchKey })
{
    @Html.TextBoxFor(m => m.Item)
    <button type="submit">Search</button>
}

搜索模型

public class SearchForm
{
    public string Item { get; set; }
}

调整布局以将参数传递回搜索小部件.这将在结果页面中保留搜索键.

Adjust your layout to pass a parameter back to the search widget. This will maintain the search key in the results page.

@Html.Action("SearchWidget", "GlobalSearch", new { item = ViewBag.GlobalSearchKey })

SearchWidget操作现在传递一个参数来填充表单(如果提供).

The SearchWidget action now passes a parameter to populate the form (if provided).

[HttpGet]
[ChildActionOnly]
public ActionResult SearchWidget(string item)
{
    var model = new SearchForm
    {
        Item = item ?? ""
    };
    return PartialView("_Search", model);
}

[HttpGet]
public ActionResult Search(SearchForm model)
{
    var results = searchService.Find(model.Item);
    ViewBag.GlobalSearchKey = model.Item;  // keep the same value for the form

    return View("SearchResults", results);  // full view with layout
}

我们使用ViewBag作为搜索关键字,因此使用布局的任何操作都不必定义通用模型.

We use the ViewBag for the search key so any action using the layout will not have to define a common model.