在.NET 4.0中,WebGrid + Paging + Sorting + Filtering中的筛选器丢失了。

14

我已经实现了一个WebGrid。排序、分页和过滤不能同时使用。当单独使用它们时,它们是有效的。如果你将这三个功能同时组合使用,过滤就无法正常工作。

症状如下:
筛选结果集,然后进行排序。

筛选结果集,然后前往下一页。

在这两种情况下,筛选结果会丢失。但是它可以进行分页和排序。

在代码后台: 当通过排序或分页调用操作方法时,每个筛选参数都显示为空值。

当通过筛选调用操作方法时,筛选参数传递成功。

这告诉我,在启动排序或分页时,它没有提交表单。

public ActionResult MyPage(int? page, int? rowsPerPage, 
              string sort, string sortdir, 
              string orderNumber, string person, string product)

我在Stack Overflow和其他地方搜索过,有很多示例和人们询问如何做到其中一个或另一个或全部三个。但是我只看到了一个与我的问题相同的问题,所以我在这里发布它。(那位的问题也没有得到解决)

我的页面实现如下:

@using (Ajax.BeginForm("MyPage", null, new AjaxOptions { InsertionMode = InsertionMode.Replace, UpdateTargetId = "myGrid" }, new { id = "filter" }))
{
    <div class="right">
        <select id="rowsPerPage" name="rowsPerPage">
            <option>15</option>
            <option>25</option>
            <option>50</option>
            <option>75</option>
            <option>100</option>
        </select>
    </div>  

    <div class="table">
        <div class="tableRow">
            <div class="tableCell">
                Order Number
            </div>
            <div class="tableCell">
                Person
            </div>
            <div class="tableCell">
                Product
            </div>
        </div>
        <div class="tableRow">
            <div class="tableCell">
                <input type="text" id="orderNumber" name="orderNumber" />
            </div>
            <div class="tableCell">
                <input type="text" id="person" name="person" />
            </div>
            <div class="tableCell">
                <input type="text" id="product" name="product" />
            </div>          
            <div class="tableCell">
                <input type="submit" class="button" value="Search" />
            </div>  
        </div>
    </div>

<br/>

<div id="myGrid">
    @Html.Partial("_MyPage", Model)
</div>

}

网格视图像这样实现:

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

@{
    var grid = new WebGrid(canPage: true, rowsPerPage: Model.rowsPerPage, canSort: true, ajaxUpdateContainerId: "grid", ajaxUpdateCallback: "resetUI");
    grid.Bind(Model.rows, rowCount: Model.TotalRecords, autoSortAndPage: false);
    @grid.GetHtml(
        tableStyle: "fancyTable",
        headerStyle: "header",
        footerStyle: "footer",
        rowStyle: "row",
        alternatingRowStyle: "alt",
        mode: WebGridPagerModes.Numeric | WebGridPagerModes.NextPrevious,
        nextText: "Next",
        previousText: "Previous",
        htmlAttributes: new { id = "grid" },
        columns: grid.Columns(
            grid.Column("OrderDate", "Order Date", format: @<text>@((item.OrderDate != null) && (item.OrderDate.ToString("MM/dd/yyyy") != "01/01/0001") ? item.OrderDate.ToString("MM/dd/yyyy") : "")</text>),
            grid.Column("OrderNumber", "Order Number"),
            grid.Column("Field1, "Field 1"),
            grid.Column("Field2", "Field 2"),
            grid.Column("Person", "Person"),
            grid.Column("Product", "Product"),
            grid.Column(format: (item) => Html.ActionLink("View", "Details", new { id = item.orderNumber }))
            )
        );
}

你找到解决方案了吗? - RredCat
请注意,ASP.NET MVC会为复选框创建额外的隐藏输入元素,而WebGrid似乎会重新解释这两个元素(如果存在于查询字符串中)为一个具有2个值的单个元素,这可能会导致在通过checkboxfor绑定模型到复选框时,在Razor中出现解析问题。我不得不使用jQuery在客户端上删除这些隐藏字段。 - Matthew Lock
3个回答

24
当构建分页和排序链接时,WebGrid助手考虑当前URL中存在的所有查询字符串参数。它会忽略POST和路由值。由于您的搜索表单是通过POST提交的,因此用户在此表单中输入的值不在查询字符串中,因此它们不是分页和排序链接的一部分,当您单击其中一个链接时,这些值将丢失。这是设计如此。
因此,解决问题的一种方法是替换您的AjaxForm:
@using (Ajax.BeginForm("MyPage", null, new AjaxOptions { InsertionMode = InsertionMode.Replace, UpdateTargetId = "myGrid" }, new { id = "filter" }))

使用GET动词和标准的HTML表单:
@using (Html.BeginForm("MyPage", null, FormMethod.Get))

或者使用GET动词的AJAX表单:

@using (Ajax.BeginForm("MyPage", null, new AjaxOptions { HttpMethod = "Get", InsertionMode = InsertionMode.Replace, UpdateTargetId = "myGrid" }, new { id = "filter" }))

现在,当用户想要过滤某些内容并点击搜索提交按钮时,他在搜索表单中输入的值将出现在查询字符串中。在呈现WebGrid助手时,这些值将用于生成其排序和分页链接,当您单击这些链接时,这些值将被发送到服务器。
如果您想对此进行更多控制,您可以考虑使用更高级的网格控件,例如MvcContrib.GridTelerik Grid for ASP.NET MVC

不,我认为它不会起作用(虽然我还没有测试过,也可能是我错了)。当您进行 AJAX 请求时(无论是 GET 还是 POST),您并未修改当前 URL。 - Darin Dimitrov
它甚至可以与 AJAX 一起使用(我已经测试过了 :)),WebGrid 内部使用 Request.QueryString 将值传递给分页器和排序链接,这些链接也会在 AJAX 请求中得到填充。 - nemesv
@nemesv,太好了,我已经更新了我的答案,包括这些信息。 - Darin Dimitrov
1
这个不起作用。整个页面,而不是网格,被放置在网格的位置。整个页面 - 甚至包括标题和搜索框。 - 101010
@010110110101 你需要返回一个带有网格的部分视图,而不是整个视图。http://www.elylucas.net/post/Using-a-grid-that-can-sort-page-and-filter-in-AspNet-MVC3e28093Part-1e28093Using-the-WebGrid-WebHelper.aspx - cederlof
显示剩余2条评论

1

将表单提交到分页链接指向的URL:

<script type="text/javascript">
     $(function () {
        $('th a, tfoot a').click(function () {
            $('form').attr('action', $(this).attr('href')).submit();
            return false;
        });
    });
</script>

这对我没有帮助,但可能对你有帮助


1

只需为您的操作方法创建一个GET,每当网格中的排序或分页触发时,它会命中GET方法以及许多参数(您可以通过指向浏览器的Web开发工具上的分页编号或排序标题来查看),在那里您可以筛选数据集,然后将模型传递给视图:

[HttpGet]
public ActionResult MyPage()

每次进行排序或分页操作时,都会调用此方法,然后您可以进行筛选,您可以添加一些静态标志,这些标志可以根据您想要筛选的内容进行分配。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接