搜索索引视图时如何添加进度指示器

时间:2014-05-31 12:40:34

标签: c# jquery asp.net-mvc

我有一个标准的索引控制器操作,包括搜索和排序,这是简化的控制器操作。

如果用户键入搜索字词并且结果需要一段时间才能从数据库中获取,如何添加进度指示器?我很困惑我是否需要使用Jquery或Microsoft ajax等。

我正在使用MVC 5和实体框架。

    public ActionResult Index(string sortOrder, 
                              string currentFilter, 
                              string searchString, 
                              int? page)
    {
        if (Request.HttpMethod == "GET")
        {
            searchString = currentFilter;
        }
        else
        {
            page = 1;
        }

        ViewBag.CurrentFilter = searchString;

        var invoices = from i in db.Invoices
                       select i;

        invoices = invoices.OrderByDescending(s => s.InvoiceDate);

        int pageSize = 20;
        int pageNumber = (page ?? 1);
        return View(invoices.ToPagedList(pageNumber, pageSize));
    }

1 个答案:

答案 0 :(得分:1)

我会有一个返回PartialViewResult的动作。然后,在您的视图上,有一个包含局部视图的容器(div或其他)。加载索引时,将使用viewmodel中的数据填充partial。然后,当用户搜索时,您对返回partial的操作进行ajax调用(使用jQuery或类似)。然后,该操作的结果将替换包含原始结果的容器的内容。在进行ajax调用之前,您可以使用jQuery显示您选择的进度指示器,并在完成/成功后再次隐藏它。

如果您需要完整的代码示例,请与我们联系。

- 这是一个基本示例(不知道有关您的代码/设置的任何其他内容):

- 注意:这只是您可以执行此操作的众多方法之一:)

我希望这有帮助!

创建一个IndexViewModel类,它将成为索引视图的模型。 viewModel将包含索引页所需的所有内容 - 包括发票列表

public class IndexViewModel
{
    // .. 
    public List<Invoice> Invoices { get; set; }
    // .. 
}

创建返回IndexViewModel的索引控制器操作:

[HttpGet]
public ViewResult Index()
{
    var model = new IndexViewModel
    {
        // ..
        // call to private method SearchInvoices with default values
        Invoices = this.SearchInvoices("ASC", string.Empty, string.Empty, 0)
        //..
    };

    return this.View(model);
}

创建另一个用于搜索的控制器操作,该操作将返回部分视图。 (这将通过jQuery / AJAX调用

public PartialViewResult Search(string sortOrder, string currentFilter, string searchString, int? page)
{
    var invoices = this.SearchInvoices(sortOrder, currentFilter, searchString, page);
    return this.PartialView("_SearchContent", invoices);
}

以下是SearchInvoices的实施

private List<Invoice> SearchInvoices(string sortOrder, string currentFilter, string searchString, int? page)
{
    // do your search work here (as you were in your original index action)
    // I would actually have this whole method implemented
    // in a separate service/business layer

    // ..
    var invoices = from i in db.Invoices select i;
    // ..

    return invoices.ToPagedList(pageNumber, pageSize);
} 

然后,您的Index.cshtml视图可能如下所示:

@model IndexViewModel

<div class="row">
    <div id="searchFieldsRow" class="col-xs-12">
        <!-- code for all of your search fields or whatever -->
    </div>
</div>

<div class="row">
    <div id="myContent" class="col-xs-12">
        <!-- display your invoices here via Partial View -->
        @Html.Partial("_SearchContent", Model.Invoices)
    </div>
</div>

<div class="row">
    <div class="col-xs-12">
        <button type="button" id="searchButton">Search</button>
    </div>
</div>

<div id="loadingProgressOverlay" class="hidden">
    Loading...
</div>

<script type="text/javascript">
    (function ($) {
        $(document).ready(function () {

            // handle the click event of your search button
            $('#searchButton').click(function () {

                // show your progress indicator
                $('#loadingProgressOverlay').show();

                // assuming you have fields for these values
                var sortOrder = $('#sortOrder').val(),
                    currentFilter = $('#currentFilter').val(),
                    searchString = $('#searchString').val(),
                    page = $('#page').val();

                // make the ajax call to your Search action on your controller
                $.ajax({
                    url: 'ControllerName/Search',
                    data: {
                        sortOrder: sortOrder,
                        currentFilter: currentFilter,
                        searchString: searchString,
                        page: page
                    },
                    type: 'POST', // OR GET, whatever you want here
                    success: function (results) {
                        // upon success:
                        // - set the html of the myContent div to the PartialViewResult output
                        // - hide your progress indicator
                        $('#myContent').html(results);
                        $('#loadingProgressOverlay').hide();
                    },
                    error: function () {
                        // handle errors properly
                    }
                });
            });
        });
    })(jQuery);
</script>

_SearchContent局部视图:

@model List<Invoice>
<table class="table">
    <thead>
        <tr>
            <!-- stuff here -->
        </tr>
    </thead>
    <tbody>
        <!-- display the list of invoices however you like -->
        @Html.DisplayForModel()
    </tbody>
</table>