使用 jQuery/jTemplate 的高效通用分页控件
一个使用 jQuery/jTemplate 的简单分页控件

引言
我开发的这个分页控件具有以下特性
- 它可以与任何 ASP.NET 数据绑定控件(如
Repeater
、GridView
等)一起使用。 - 它具有非常好的可伸缩性、高效性,并且对数据库友好。
- 它非常容易实现和理解。
这是主要思路
首先是此控件的数据库部分。所有的技巧都在这里。我使用了一个 Repeater
控件作为数据绑定控件,我的分页控件将在此基础上工作。但它可以在任何数据绑定控件上工作。例如,绑定此 repeater 控件的查询输出如下

该 repeater 控件每页显示 5 条记录。目前,这个“记录数”是在逻辑中硬编码的。AddressID
字段是数字类型,并且是主键。基本上,我只在客户端存储每页的第一个 AddressId
。
因此,对于上面的查询,我会在客户端保存以下起始 AddressID
。
AddressID = 859 (Page# 1)
AddressID = 15460 (Page# 2)
AddressID = 20017 (Page# 3)
AddressID = 25816 (Page# 4)
AddressID = 27652 (Page# 5)
现在,当通过单击“下一页/上一页”按钮或通过下拉列表选择更改页面索引时,jQuery-AJAX 会在数据库上触发一个查询,传递起始 AddressID
。它检索以提供的 AddressID
开头的 5 条记录。这是一个例子
[WebMethod]
public static List<RepeaterData> getRepeaterData(int nStartAddressID)
{
List<RepeaterData> _RepeaterData = new List<RepeaterData>();
SqlDataReader reader = null;
DataTable dt = new DataTable();
using (SqlConnection conn = new SqlConnection())
{
conn.ConnectionString = ConfigurationManager.ConnectionStrings
["ConnStr2"].ConnectionString;
using (SqlCommand cmd = new SqlCommand())
{
//Instead of Dynamic SQL , please use StoredProc for better design.
//The SqlParameter will protect against any SQL injection
//as well as the strong int data-type for the variable nStartAddressID.
cmd.CommandText = "SELECT TOP (5) AddressID, AddressLine1,
City, PostalCode " +
"FROM [AdventureWorks].[Person].[Address] " +
"WHERE AddressLine1 like '105%' " +
"and AddressID >= @AddressID " +
"ORDER BY AddressID";
cmd.Parameters.Add("@AddressID", SqlDbType.Int).Value = nStartAddressID;
cmd.Connection = conn;
StringBuilder sb = new StringBuilder();
conn.Open();
reader = cmd.ExecuteReader();
dt.Load(reader);
conn.Close();
}
}
foreach (DataRow dr in dt.Rows)
{
RepeaterData lp = new RepeaterData();
lp.AddressID = int.Parse(dr["AddressID"].ToString());
lp.AddressLine1 = dr["AddressLine1"].ToString();
lp.City = dr["City"].ToString();
lp.PostalCode = dr["PostalCode"].ToString();
_RepeaterData.Add(lp);
}
return _RepeaterData;
}
在这个例子中,我使用了动态 SQL,但为了更好的设计,请尝试使用 StoredProc
代替。在这种情况下,SqlParameter
将防止任何 SQL 注入。请注意,变量 nStartAddressID
是一个 int
,这也防止了各种注入攻击。
这里需要注意的是,在第一次 PageLoad
时,我绑定了 Repeater
、Dropdownlist
,并从代码后端设置了 JavaScript 变量。一旦页面加载完成,所有操作都是通过 jQuery AJAX 使用 jTemplate 进行的。没有回发。
由于 Repeater 本身不发出任何 HTML,因此在 AJAX 调用完成后,jTemplate 可以轻松地替换 Repeater
的 HTML。
在最初的第一次 pageLoad
中,我使用了一个稍微不同的查询来获取前 5 行。
SELECT ROW_NUMBER () OVER (ORDER BY AddressID) AS RowNumber, _
AddressID, AddressLine1, City, PostalCode
FROM [AdventureWorks].[Person].[Address] where AddressLine1 _
like '105%' ORDER BY AddressID;
您可以使用带有 SqlParameter
的 StoredProc
来使其免受注入攻击。 我这里只是试图演示这个概念。
正如您所看到的,我在我的 DataView
中获得了行号,并使用它来抓取前 5 条记录。 但是,在任何后续分页操作中,我都会使用起始 addressID
来获取相关的 5 条记录。 这就是我的意思。
在客户端,初始 pageLoad
时,页面编号和相应的起始 AddressID
是这样存储的。
var js1=[{"PagerNums":1,"AddressID":859},
{"PagerNums":2,"AddressID":15460},{"PagerNums":3,"AddressID":20017},
{"PagerNums":4,"AddressID":25816},{"PagerNums":5,"AddressID":27652}]
正如您所看到的,我只需要跟踪当前页面所在的页面编号。 因此,当单击“上一页/下一页”按钮或更改下拉列表选择时,我会从当前页码中找出起始 AddressID
,并将该 AddressID
作为参数提供给 AJAX DB 调用。
function UpdatePrevNextClick() {
$.ajax({
type: "POST",
url: "PagerRepeater4.aspx/getRepeaterData",
data: "{ 'nStartAddressID': '" + CurAddrID + "' }",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
$('#RptPager').setTemplateURL('JTemplates/PagerTemplate.htm');
$('#RptPager').processTemplate(data.d);
HidePrevNextButton();
UpdateDDL();
}
});
}
分页操作主要取决于数据绑定控件所在的当前页码。 分页有 3 个触发器,即 - 单击“下一页”按钮、单击“上一页”按钮或从下拉列表中选择页码。
让我们详细了解一下当用户从下拉列表中选择任何页码时的情况。
分页器中的下拉列表包含所有唯一的页码。
因此,当用户选择任何所需的页码时,我会从客户端存储的 JS 数组中找出相应的起始 AddressID
。
这是代码
<script type="text/javascript">
var Totalpages = 0;
$(document).ready(function () {
var dropDownList1 = $('select[id$=ddl1]');
Totalpages = dropDownList1[0].length;
$('.b1').html(dropDownList1[0].length);
HidePrevNextButton();
dropDownList1.change(function (e) {
CurPageNum = this.value;
CurAddrID = js1[CurPageNum-1].AddressID;
UpdatePrevNextClick();
});
});
</script>
一旦我获得了起始 Address ID,我就通过 jQuery AJAX 异步触发查询,如上所述。 当页面的相关部分刷新时,我总是验证是否有必要显示/隐藏“上一页/下一页”按钮。 当加载第一页时,“上一页”按钮会被隐藏,类似地,当隐藏最后一页时,“下一页”按钮会被隐藏。
这就是全部。 感谢阅读。
历史
- 2011-05-05: 版本 1