我在表格中显示了大量数据,让我们说一长串用户(名字和姓氏),所以我设置了一个分页功能,通过PagedList NuGet包按页显示元素。我受到本教程的启发:https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application
我在视图中实现了一个下拉列表,这样我就可以直接选择每页显示的元素数量。我设法包含一个jQuery脚本,只要下拉列表中有一个新的选定值,就会更新页面大小。
使用上述教程,我还添加了搜索功能:以搜索表单提交字符串可以过滤数据。
我的问题是:通过在下拉列表中选择新值来更改页面大小完成搜索后不起作用:重置搜索结果,所有条目正在显示。我想我忘了在某个地方传递一些参数,但我无法弄清楚在哪里......
这是我的控制器:
public ActionResult Index(string sortOrder, string currentFilter, string searchString, int? page, int? PageSize)
// Sort order is passed to view in order to keep it intact while clicking in another page link
ViewBag.CurrentSort = sortOrder;
// Ascending or descending sorting by first or last name according to sortOrder value
ViewBag.LastNameSortParm = String.IsNullOrEmpty(sortOrder) ? "lastname_desc" : "";
ViewBag.FirstNameSortParm = sortOrder == "firstname" ? "firstname_desc" : "firstname";
// Not sure here
if (searchString == null)
{
searchString = currentFilter;
}
// Pass filtering string to view in order to maintain filtering when paging
ViewBag.CurrentFilter = searchString;
var users = from u in _db.USER select u;
// FILTERING
if (!String.IsNullOrEmpty(searchString))
{
users = users.Where(u => u.lastname.Contains(searchString)
|| u.firstname.Contains(searchString)
}
// Ascending or descending filtering by first/last name
switch (sortOrder)
{
case "lastname": // Ascending last name
users = users.OrderBy(u => u.lastname);
break;
case "lastname_desc": // Descending last name
users = users.OrderByDescending(u => u.lastname);
break;
case "firstname": // Ascending first name
users = users.OrderBy(u => u.firstname);
break;
case "firstname_desc": // Descending first name
users = users.OrderByDescending(u => u.firstname);
break;
default:
users = users.OrderBy(u => u.lastname);
break;
}
// DROPDOWNLIST FOR UPDATING PAGE SIZE
int count = _db.USER.OrderBy(e => e.Id).Count(); // Total number of elements
// Populate DropDownList
ViewBag.PageSize = new List<SelectListItem>() {
new SelectListItem { Text = "10", Value = "10", Selected = true },
new SelectListItem { Text = "25", Value = "25" },
new SelectListItem { Text = "50", Value = "50" },
new SelectListItem { Text = "100", Value = "100" },
new SelectListItem { Text = "All", Value = count.ToString() }
};
int pageNumber = (page ?? 1);
int pageSize = (PageSize ?? 10);
ViewBag.psize = pageSize;
return View(users.ToPagedList(pageNumber, pageSize));
}
我的Index.cshtml视图:
<script src="~/Scripts/jquery-3.2.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () { // Submit pageSizeForm when another pageSize value is selected
$("#pageSize").change(function () {
$("#pageSizeForm").submit();
});
});
</script>
@model PagedList.IPagedList<AfpaSIPAdmin.Models.USER>
@using PagedList.Mvc;
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
@{
ViewBag.Title = "Users management";
}
<h1>Users management</h1>
<!-- Creating a new entry in table -->
<p>
@Html.ActionLink("Create new user", "Create")
</p>
<!-- Filtering table entries -->
@using (Html.BeginForm("Index", "Users", FormMethod.Get, new { id = "filterForm" }))
{
<p>
Filter: @Html.TextBox("SearchString", ViewBag.CurrentFilter as string, new { @placeholder = "First or last name..." })
<input type="submit" value="Apply"/>
</p>
}
<!-- Display table -->
<table class="table">
<tr>
<th>
@Html.ActionLink("Last name", "Index", new {
sortOrder = ViewBag.LastNameSortParm,
currentFilter = ViewBag.CurrentFilter
})
</th>
<th>
@Html.ActionLink("First name", "Index", new {
sortOrder = ViewBag.FirstNameSortParm,
currentFilter = ViewBag.CurrentFilter
})
</th>
<th style="min-width: 170px"></th>
</tr>
@foreach (var item in Model)
{
<tr>
<td style = "min-width: 150px">
@Html.DisplayFor(modelItem => item.lastname)
</td>
<td style = "min-width: 150px">
@Html.DisplayFor(modelItem => item.firstname)
</td>
<td> <!-- Using images as buttons for actions -->
<a href="@Url.Action("Edit", "Users", new { id = item.Id })" title="Edit">
<img src="~/Content/images/edit.gif" />
</a>
<a href="@Url.Action("Details", "Users", new { id = item.Id })" title="Details">
<img src="~/Content/images/info.gif" />
</a>
<a href="@Url.Action("Delete", "Users", new { id = item.Id })" title="Delete">
<img src="~/Content/images/delete.gif" />
</a>
</td>
</tr>
}
</table>
<br/>
<!-- Paging -->
@using (Html.BeginForm("Index", "Users", FormMethod.Get, new { id = "pageSizeForm" }))
{
<div class="pager">
Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) sur @Model.PageCount<br/>
@Model.Count of @Model.TotalItemCount elements
@Html.PagedListPager(Model, page => Url.Action("Index", new {
page,
sortOrder = ViewBag.CurrentSort,
currentFilter = ViewBag.CurrentFilter,
searchString = ViewBag.CurrentFilter,
pageSize = ViewBag.psize
}))
<!-- DropDownList for setting page size -->
Elements per page :
@Html.DropDownList("pageSize")
</div>
}
答案 0 :(得分:1)
原因是因为你有2个表格。当您提交包含文本框的第一个表单时,您发送回控制器的唯一值是SearchString
,并且您方法中的所有其他参数将是它们的默认值(例如,当您返回视图时,{{1}默认为PageSize
,因此即使之前选择的用户说50,也只返回10条记录。
同样,当您提交包含页面大小下拉列表的第二个表单时,null
的值将为SearchString
,因为它未在请求中发送。
您需要只有一个包含两个表单控件的表单。如果要发送其他属性(例如当前排序顺序),则可以将其作为查询字符串值添加到表单元素中(例如,null
我还强烈建议您使用包含视图中所需属性的视图模型,并强烈绑定它们而不是使用@using(Html.BeginForm("Index", "Users", new { sortOrder = .... }, FormMethod.Get))
ViewBag
查看
public class UsersVM
{
public string SearchString { get; set; }
public int PageSize { get; set; }
public IEnumerable<SelectListItem> PageSizeOptions { get; set; }
.....
public IPagedList<USER> Users { get; set; }
}
并在控制器方法中,初始化@model UsersVM
...
@using(Html.BeginForm("Index", "Users", FormMethod.Get))
{
@Html.LabelFor(m => m.SearchString)
@Html.TextBoxFor(m => m.SearchString)
@Html.LabelFor(m => m.PageSize)
@Html.DropDownListFor(m => m.PageSize, Model.PageSizeOptions)
<input type="submit" value="Filter" />
}
....
<div class="pager">
Page @(Model.Users.PageCount < Model.Users.PageNumber ? 0 : Model.Users.PageNumber)
....
@Html.PagedListPager(Model.Users, page => Url.Action("Index", new {
page,
sortOrder = Model.CurrentSort,
currentFilter = Model.CurrentFilter,
searchString = Model.CurrentFilter,
pageSize = Model.PageSize
}))
</div>
的新实例并分配其属性
UsersVM