[英]Custom pagination, “next” and “last” button doesn't work properly
我目前正在c#asp.net中为我的简单项目创建自定义分页,到目前为止,效果很好,但是“下一步”和“最后一个”按钮无法正常工作。 “下一页”按钮仅返回当前页面,或者如果我位于大于1的另一页面上,则返回上一页。
“最后一个”按钮没有按预期转到最后一页。
我知道这只是视图中for
循环中的内容,或者在models文件中缺少了某些内容。
到目前为止,这是我的代码:
Index.cshtml(查看)
@model FinalPaginationTask.Models.UserCustom
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="Content/***.css" />
<title> </title>
</head>
<body>
<h2>List of Users</h2>
@using (Html.BeginForm(null, null, FormMethod.Post))
{
@Html.AntiForgeryToken()
@Html.Hidden("SortField", Model.SortField)
@Html.Hidden("SortDirection", Model.SortDirection)
@Html.Hidden("PageCount", Model.PageCount)
@Html.Hidden("PageSize", Model.PageSize)
@Html.Hidden("CurrentPageIndex", Model.CurrentPageIndex)
@*@Html.Hidden("SelectedUsr_Id", Model.SelectedUsr_Id)
@Html.Hidden("SelectedUsername", Model.SelectedUsername)*@
<table id="customers" class="table-striped">
<tr>
<th >
<a href="#" data-sortfield="usr_Id" class="header">@Html.DisplayNameFor(model => model.user.First().usr_Id)</a>
</th>
<th>
<a href="#" data-sortfield="username" class="header">@Html.DisplayNameFor(model => model.user.First().username)</a>
</th>
<th>
@Html.DisplayNameFor(model => model.user.First().email)
</th>
<th>
</th>
</tr>
<tr>
@*<th>
@Html.DropDownListFor(model => model.SelectedUsr_Id,
new SelectList(Model.userDDL, "usr_Id", "usr_Id", Model.SelectedUsr_Id), "All", new { @id = "fn" })
</th>
<th>
@Html.DropDownListFor(model => model.SelectedUsername,
new SelectList(Model.userDDL, "username", "username", Model.SelectedUsername), "All", new { @id = "ln" })
</th>*@
</tr>
@foreach (var item in Model.user)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.usr_Id)
</td>
<td>
@Html.DisplayFor(modelItem => item.username)
</td>
<td>
@Html.DisplayFor(modelItem => item.email)
</td>
<td>
@Html.ActionLink("Create User", "CreateUser", new { /* id=item.PrimaryKey */ }) |
@Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
@Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
@Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
</td>
</tr>
}
<tr></tr>
@*@if (Model.Pager.LastPage > 1)
{*@
<tr class="pagination">
@if (Model.CurrentPageIndex >= 1)
{
<td class="pager"><a href="~/User/">First</a></td>
<td class="pager"><a href="~/User/Index/@(Model.CurrentPageIndex - 1)">Previous</a></td>
}
@for (var i = 0; i < Model.PageCount; i++)
{
if (i == Model.CurrentPageIndex)
{
<td class="pager"><span class="current-pager" id="CurrentPageIndex">@(i + 1)</span></td>
}
else
{
<td class="pager" ><a href="~/User/Index/@i" data-pageindex="@i" class="pager">@(i + 1)</a></td>
}
}
@if (Model.CurrentPageIndex < Model.PageCount)
{
<td class="pager"><a href="~/User/Index/@(Model.CurrentPageIndex + 1)">Next</a></td>
<td class="pager"><a href="~/User/Index/@(Model.PageCount)">Last</a></td>
}
</tr>
@*}*@
</table>
}
</body>
</html>
<script type="text/javascript">
$(document).ready(function () {
$(".header").click(function (evt) {
var sortfield = $(evt.target).data("sortfield");
if ($("#SortField").val() == sortfield) {
if ($("#SortDirection").val() == "ascending") {
$("#SortDirection").val("descending");
}
else {
$("#SortDirection").val("ascending");
}
}
else {
$("#SortField").val(sortfield);
$("#SortDirection").val("ascending");
}
evt.preventDefault();
$("form").submit();
});
$(".pager").click(function (evt) {
var pageindex = $(evt.target).data("pageindex");
$("#CurrentPageIndex").val(pageindex);
evt.preventDefault();
$("form").submit();
});
$("#fn").change(function (evt) {
$("#SelectedUsr_Id").val($("#fn").val().trim());
evt.preventDefault();
$("form").submit();
})
$("#ln").change(function (evt) {
$("#SelectedUsername").val($("#ln").val().trim());
evt.preventDefault();
$("form").submit();
})
});
</script>
模型:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace FinalPaginationTask.Models
{
public class SortAndPage // used for sorting and paging
{
public string SortField{ get; set; }
public string SortDirection { get; set; }
public int PageSize { get; set; }
public int PageCount { get; set; }
public int StartPage { get; set; }
public int LastPage { get; set; }
public int CurrentPageIndex { get; set; }
public Pager Pager { get; set; }
}
}
任何帮助将不胜感激。 非常感谢你!
编辑:我将添加我的控制器,因为可能需要其他信息:
public ActionResult Index(UserCustom userCustomModel = null)
{
// start load customer
//int i;
//if (userCustomModel != null)
//{
// i = userCustomModel.CurrentPageIndex;
//}
userCustomModel = new UserCustom
{
user = db.Users.ToList(),
userDDL = db.Users.ToList()
};
// end load customer
var res = (from s in userCustomModel.user
select s);
res = res.ToList(); /// select all users from the database
if (userCustomModel.CurrentPageIndex == 0)
{
userCustomModel.CurrentPageIndex = 0;
}
userCustomModel.PageSize = 10;
userCustomModel.PageCount = ((res.Count() + userCustomModel.PageSize - 1) / userCustomModel.PageSize);
// (7 + 5 - 1) = 11 / 5 = 2 pages
if (userCustomModel.CurrentPageIndex > userCustomModel.PageCount)
{
userCustomModel.CurrentPageIndex = userCustomModel.PageCount;
}
userCustomModel.user = res.Skip(userCustomModel.CurrentPageIndex * userCustomModel.PageSize).Take(userCustomModel.PageSize);
// 0 * 5 = 0 (5)
// 1 * 5 = 5 skip 5.take 5-10
return View(userCustomModel);
}
向用户显示的数字和索引之间存在差异。 索引值的范围是0 .. PageCount-1
,显示的数字范围是1 .. PageCount
。
现在,如果我们查看“ Next
和“ Last
链接,则可以看到两种方法的混淆:
<td class="pager"><a href="~/User/Index/@(Model.CurrentPageIndex + 1)">Next</a></td>
<td class="pager"><a href="~/User/Index/@(Model.PageCount)">Last</a></td>
第一个链接增加CurrentPageIndex
,这是一种有效的方法。 但是第二个将索引设置为PageCount
,而索引的范围为0 .. PageCount-1
如我们所建立的0 .. PageCount-1
。 这或许可以解释为什么Last
的链接不工作,但Next
的链接应该在这种情况下工作。
还要检查:
@if (Model.CurrentPageIndex < Model.PageCount)
始终为true,因为CurrentPageIndex
最多为PageCount-1
。
我建议为您的Index
操作方法设置一个断点,并尝试各个链接以查看所获得的值以及它们是否符合您的期望。 虽然尚不清楚Next
链接为什么不起作用,但应该可以根据描述从代码中找出答案。
“下一页”按钮仅返回当前页面,或者如果我位于大于1的另一页面上,则返回上一页。
从这种行为,我怀疑代码隐藏处理会从page
参数中减去1,因此URL期望值的范围是1 .. PageCount
但您提供的值范围是0 .. PageCount-1
。
将动作方法代码添加到您的问题中之后( Controller
中的每个公共方法都习惯上称为ASP.NET中的action method
:-)),我将根据自己的发现更新代码。
首先,您的代码包含以下检查:
if (userCustomModel.CurrentPageIndex == 0)
{
userCustomModel.CurrentPageIndex = 0;
}
您可以摆脱它,因为它不会改变任何东西:-)。
但是,主要问题在这里:
userCustomModel = new UserCustom
{
user = db.Users.ToList(),
userDDL = db.Users.ToList()
};
在这里,您正在设置userCustomModel
来的新实例UserCustom
基本上覆盖你从请求URL收到的值。 如果仅在null
时初始化变量,然后直接在下一行从数据库查询,则代码应该可以工作:
public ActionResult Index(UserCustom userCustomModel = null)
{
//initialize only if null
if ( userCustomModel == null )
{
userCustomModel = new UserCustom();
}
// end load customer
var res = db.Users.ToList(); // select all users from the database
userCustomModel.PageSize = 10;
userCustomModel.PageCount = ((res.Count() + userCustomModel.PageSize - 1) / userCustomModel.PageSize);
// (7 + 5 - 1) = 11 / 5 = 2 pages
if (userCustomModel.CurrentPageIndex > userCustomModel.PageCount)
{
userCustomModel.CurrentPageIndex = userCustomModel.PageCount;
}
userCustomModel.user = res.Skip(userCustomModel.CurrentPageIndex * userCustomModel.PageSize).Take(userCustomModel.PageSize);
// 0 * 5 = 0 (5)
// 1 * 5 = 5 skip 5.take 5-10
userCustomMode.userDDL = res;
return View(userCustomModel);
}
如果这不起作用,请检查路由,如果您的路由参数实际上称为CurrentPageIndex
。 您的操作方法参数可以简化为仅使用一个int
:
public ActionResult Index(int currentPageIndex = 0)
现在,您的代码可以在每次使用currentPageIndex
变量作为当前页面时初始化userCustomModel
。
伙计,我不知道您为什么需要通过提交表单来处理导航。
请备注一下:
//$(".pager").click(function (evt) {
// var pageindex = $(evt.target).data("pageindex");
// $("#CurrentPageIndex").val(pageindex);
// evt.preventDefault();
// $("form").submit();
//});
然后再试一次。
希望对您有所帮助,因为我没有使用上面更新的控制器就尝试了此操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.