使用 JavaScript 在 ASP.NET 中实现支持 Ajax 的 Gridview






4.74/5 (33投票s)
我创建了一个 JavaScript Gridview,它具有与显示记录的表格格式、分页、排序、删除和在运行时更改页面大小而无需回发的相同操作。

引言
在解释文章之前,我想感谢所有阅读我的文章并为其投票的读者。你们对我文章的赞赏给了我写更多好文章的动力。希望未来我能收到你们宝贵的评论和建议。现在我将不再浪费你们的时间,回到主题。我写这篇文章是关于“使用 JavaScript 在 ASP.NET 中实现支持 Ajax 的 Gridview”。在这篇文章中,我将向你们展示如何仅使用简单的 HTML 表格、JavaScript 和 XML HTTP 进行 Ajax 调用,而无需使用任何 ASP.NET 控件来创建一个 Gridview。
使用代码
使用此 JavaScript Gridview,您可以执行 Gridview 的常规操作,例如以表格格式显示数据、分页查看记录、在运行时排序数据而无需回发。此外,您可以删除记录并设置页面大小。
我们将在以下部分介绍本文:
- 从数据源请求数据。
- 将 Gridview 与数据绑定或创建 HTML 表格以表格格式显示数据。
- 创建分页控件。
- 在运行时设置分页大小。
- 从网格中删除记录。
现在让我们开始第一步。
1. 从数据源请求数据
我使用了一个 default.aspx 页面在该页面上显示一个网格。页面加载时,会在 body
标签的 onload
事件上调用 JavaScript 函数 fnFillGrid()
。
function fnFillGrid()
{
GetResponse('HandleRequest.ashx?RequestType=ShowCart' ,GetCartResponse)
}
函数 fnFillGrid()
本身会调用一个 GetResponse()
函数,该函数有两个参数:一个 URL 和一个用于处理响应的函数。通过异步调用来发送请求并从服务器获取响应。
function GetResponse(url, Response)
{
if(navigator.appName == "Microsoft Internet Explorer")
{
var xhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
else
{
var xhttp = new XMLHttpRequest();
}
xhttp.open("GET", url, true);
xhttp.onreadystatechange =
function()
{
if (xhttp.readyState == 4 && xhttp.responseText)
{
validateResponse(xhttp);
Response(xhttp.responseXML);
}
}
xhttp.send(null);
}
在 URL 参数中,您会看到一个名为 handlerequest.ashx 的通用处理程序文件。请求将使用一个查询字符串 RequestType
发送到服务器上的此文件,该查询字符串确定服务器上要处理的请求类型。
从 Web 服务器,响应以 XML 格式返回。
在这里,我将向您展示服务器如何处理请求并以 XML 格式发送响应。
当一个请求发送到 Web 服务器上的 handlerequest.ashx 时,会调用一个名为 ProcessRequest()
的函数。在 ProcessRequest
函数中,我声明了一个 XmlTextWriter
XML 对象。使用此 XML 对象,会在内存中创建一个 XML 文件并作为响应发送。
XmlTextWriter xml = new XmlTextWriter(context.Response.Output);
xml.WriteStartElement("Root");
要创建 XML 文件,使用了 XmlTextWritter
的三个函数:
WriteStartElement(NodeName)
WriteElementstring()
WriteEndElement()
WriteStartElement
函数用于开始 XML 文件的 root
元素,WriteElementString()
用于创建 Root
元素的子元素。最后,WriteendElement()
用于关闭 Root
元素的标签。
XML 文件的结构将采用以下格式:
<Root>
<Product>…….</Product>
<ProductId>…….</ProductId>
…………………………………………….
……………………………..………………
</Root>
现在,使用一个数据集从存储在应用程序文件夹的 App_Data 文件夹中的 XML 文件 cart.xml 读取数据。
从数据源读取数据后,将记录插入到 Root
元素的子元素中,位于 <Root>
标签之间,然后将其作为响应发送。
DataSet DS = new DataSet();
DS.ReadXml(HttpContext.Current.ApplicationInstance.Server.MapPath
("~/App_Data/Cart.xml"));
double TotalMRP=0;
double TotalDiscount=0;
double GrantTotal=0;
if(DS.Tables.Count>0)
foreach (DataRow dr in DS.Tables[0].Rows)
{
double PriceTotal =Convert.ToDouble(dr["MRP"].ToString()) -
Convert.ToDouble(dr["Discount"].ToString());
PriceTotal *= Convert.ToDouble(dr["Qty"].ToString());
TotalMRP += Convert.ToDouble(dr["MRP"].ToString());
GrantTotal += PriceTotal;
TotalDiscount += Convert.ToDouble(dr["Discount"].ToString());
xml.WriteStartElement("Product");
xml.WriteElementString("ProductId", dr["ProductId"].ToString());
xml.WriteElementString("ProductName", dr["ProductName"].ToString());
xml.WriteElementString("Category", dr["Category"].ToString());
xml.WriteElementString("MRP", dr["MRP"].ToString());
xml.WriteElementString("Discount", dr["Discount"].ToString());
xml.WriteElementString("Qty", dr["Qty"].ToString());
xml.WriteElementString("PriceTotal", PriceTotal.ToString());
xml.WriteElementString("TotalMRP", TotalMRP.ToString());
xml.WriteElementString("TotalDiscount", TotalDiscount.ToString());
xml.WriteElementString("GrantTotal", GrantTotal.ToString());
xml.WriteEndElement();
}
现在响应发送到浏览器。
在第二步中,我将向您展示如何将此响应数据绑定到网格。
2. 将 Gridview 与数据绑定
我们知道响应是以 XML 格式发送的,因此数据是按标签逐个检索并存储在相应的数组中。稍后处理这些数组以形成网格数据。
var ProductNameList = XML.getElementsByTagName('ProductName');
var ProductIdList = XML.getElementsByTagName('ProductId');
var MRPList = XML.getElementsByTagName('MRP');
var DiscountList = XML.getElementsByTagName('Discount');
var CategoryList = XML.getElementsByTagName('Category');
var QtyList = XML.getElementsByTagName('Qty');
var PriceTotalList= XML.getElementsByTagName('PriceTotal');
var TotalMRPList= XML.getElementsByTagName('TotalMRP');
var TotalDiscountList= XML.getElementsByTagName('TotalDiscount');
var GrantTotalList= XML.getElementsByTagName('GrantTotal');
现在,网格的项在这里创建。
strTable = strTable + '<tr class="gvHeader" >';
strTable = strTable + ' <td style=width:8% align=center>';
strTable = strTable + ' Delete' ;
strTable = strTable + ' </td>';
strTable = strTable + ' <td style=width:30% class=gvHeader align=center>';
strTable = strTable + ' Product Name';
strTable = strTable + ' </td>';
strTable = strTable + ' <td style=width:24% class=gvHeader align=center>';
strTable = strTable + ' Category';
strTable = strTable + ' </td>';
strTable = strTable + ' <td style=width:10% class=gvHeader align=center>';
strTable = strTable + ' MRP';
strTable = strTable + ' </td>';
strTable = strTable + ' <td style=width:10% class=gvHeader align=center>';
strTable = strTable + ' Discount';
strTable = strTable + ' </td>';
strTable = strTable + ' <td style=width:8% class=gvHeader align=center>';
strTable = strTable + ' Quantity';
strTable = strTable + ' </td>';
strTable = strTable + ' <td style=width:10% class=gvHeader align=center >';
strTable = strTable + ' Total';
strTable = strTable + ' </td>';
strTable = strTable + '</tr>';
创建表格后,将其作为 innerHTML
分配给一个 div
控件 gvCart
。
现在我们有了一个 JavaScript Gridview。
3. 创建分页控件
为了创建分页控件,我使用了默认的页面大小 3
。页数是通过将 ProductIdList
数组的长度除以页面大小来确定的。每次分页都有一个 onclick
事件,当用户单击页码时会触发该事件。
要创建页码链接,我们有这段代码。
for(var pageCount=1 ; pageCount<=Math.ceil(ProductIdList.length/PageSize);pageCount++)
{
Pagelink= Pagelink + '<a href=javascript:void(0)
onclick=javacsript:PageIndexChanging('+ (pageCount-1) + ');
id=a_'+ pageCount+'> ' + (pageCount) + '</a>'
}
当用户更改页面时,会调用 PageIndexChanging
函数,我们在其中更改页面内容。
在这里,我没有发送任何页面数据请求。我只是将页面行隐藏或显示,即当用户将页码从 1 更改为 2 时,属于第 2 页的所有行都会显示出来,而其他页面的所有行都会被隐藏。
以下代码执行此操作:
var arrProduct;
arrProduct = document.getElementsByName('chkSelect');
for (var i=0; i< arrProduct.length ; i++)
{
if(i >=(PageNo*PageSize) && i < (PageNo+1)*PageSize)
document.getElementById('trSelect'+i).style.display=''
else
document.getElementById('trSelect'+i).style.display='none'
}
在 if
条件中,您将看到我显示了属于选定页面的所有行,并将其余行隐藏。
现在进行第四步。
4. 在运行时设置分页大小
使用一个下拉列表来在运行时更改网格的页面大小。默认页面大小设置为 3
。
var PageSize=3;
if(document.getElementById('ddlPageSize'))
PageSize = document.getElementById('ddlPageSize').value;
第一次绑定网格时,我们实际上还没有创建分页下拉列表。所以默认大小是 3
。但是当我们更改页面大小时,我们就有分页下拉列表,可以从中获取页面大小的值。在这里,我们可以从下拉列表中设置网格的页面大小。
现在进入最后一步 5。
5. 从网格中删除记录
要从网格中删除记录,我们需要一个复选框来选择,一个按钮来删除记录。为此,我创建了一个名为 btnDelete
的按钮和一个名为 DeleteItem()
的函数,当用户单击删除按钮时会触发该函数。
var arrProduct;
arrProduct = document.getElementsByName('chkSelect');
var ProdIds='';
for (var i=0 ; i<arrProduct.length ; i++)
{
if(arrProduct[i].checked)
{
ProdIds = ProdIds + arrProduct[i].id.substring(7,arrProduct[i].id.length) + ',';
}
}
if(ProdIds !='')
{
if(confirm('Are you sure want to delete selected item(s)?'))
{
ProdIds=ProdIds.substring(0,ProdIds.length-1)
GetResponse('HandleRequest.ashx?RequestType=DeleteCart&ProdIds='+
ProdIds,GetCartResponse);
}
}
else
{
alert('Please select item(s) to delete.');
}
在这个 JavaScript 函数中,我找到了所有被选中的复选框,然后将它们作为请求发送到服务器以删除这些项,并从服务器接收新的响应以用剩余的记录填充网格。复选框的值在页面更改期间得以保留。
历史
- 2009年2月15日:初始发布