最近在學習Ajax,這真是個好東西啊,能大大調高用戶的體驗,異步式的開發着實很爽,前段時間剛學asp.net webform時候,沒有ajax有很多操作要不同的頁面進行操作,要不停的跳轉,如果頁面再有一堆服務端控件,着實不爽,體驗特別的不舒服.Ajax是什么東西,我就不說了,大家都知道,本人剛學這個,發現寫js代碼十分的不熟,以后要多練練,下面我就分享我學習過程中的一些實際運用Ajax的Demo,着實沒什么技術,純粹的分享,讓沒有學過Ajax的能夠了解Ajax的一些基本用法,大家共同學習,共同進步,Demo很簡單利用AJAX的CRUD和分頁等..
加載數據跟分頁
首先我們自己搭建個表,具體的字段可以自己來設置,然后增加點數據即可,自己寫分頁存儲過程,這個分頁存儲我直接用的代碼生成器生成,其實大家可以根據自己的需求來寫分頁,然后我是用的三層,如果自己寫分頁存儲過程,可以自己寫Dal層的代碼,會比較麻煩,但是寫一次以后都能用了..我偷懶了直接用動軟那套了.然后分頁還需要一個生成html字符串的代碼,用於在前台生成頁碼超鏈接,我本來想把它改成JS方法的,但是沒成功,js實在爛,這樣可以再后台穿參數過去即可,不需要傳html標簽字符串,增加傳輸量,具體的如下:
public static string ShowPageNavigate(int pageSize, int currentPage, int totalCount)
{
string redirectTo = "";
pageSize = pageSize == 0 ? 3 : pageSize;
var totalPages = Math.Max((totalCount + pageSize - 1) / pageSize, 1); //總頁數
var output = new StringBuilder();
if (totalPages > 1)
{
if (currentPage != 1)
{//處理首頁連接
output.AppendFormat("<a class='pageLink' href='{0}?pageIndex=1&pageSize={1}'>首頁</a> ", redirectTo, pageSize);
}
if (currentPage > 1)
{//處理上一頁的連接
output.AppendFormat("<a class='pageLink' href='{0}?pageIndex={1}&pageSize={2}'>上一頁</a> ", redirectTo, currentPage - 1, pageSize);
}
else
{
// output.Append("<span class='pageLink'>上一頁</span>");
}
output.Append(" ");
int currint = 5;
for (int i = 0; i <= 10; i++)
{//一共最多顯示10個頁碼,前面5個,后面5個
if ((currentPage + i - currint) >= 1 && (currentPage + i - currint) <= totalPages)
{
if (currint == i)
{//當前頁處理
//output.Append(string.Format("[{0}]", currentPage));
output.AppendFormat("<a class='cpb' href='{0}?pageIndex={1}&pageSize={2}'>{3}</a> ", redirectTo, currentPage, pageSize, currentPage);
}
else
{//一般頁處理
output.AppendFormat("<a class='pageLink' href='{0}?pageIndex={1}&pageSize={2}'>{3}</a> ", redirectTo, currentPage + i - currint, pageSize, currentPage + i - currint);
}
}
output.Append(" ");
}
if (currentPage < totalPages)
{//處理下一頁的鏈接
output.AppendFormat("<a class='pageLink' href='{0}?pageIndex={1}&pageSize={2}'>下一頁</a> ", redirectTo, currentPage + 1, pageSize);
}
else
{
//output.Append("<span class='pageLink'>下一頁</span>");
}
output.Append(" ");
if (currentPage != totalPages)
{
output.AppendFormat("<a class='pageLink' href='{0}?pageIndex={1}&pageSize={2}'>末頁</a> ", redirectTo, totalPages, pageSize);
}
output.Append(" ");
}
output.AppendFormat("第{0}頁 / 共{1}頁", currentPage, totalPages);//這個統計加不加都行
return output.ToString();
}
有了這個類,我們下面還是着手第一件事:加載數據到頁面,這是我用的純html頁面跟一般處理程序來處理,避免走webform那一陀的生命周期,首先需要一個展示UserList的頁面和一個加載數據的一般處理程序LoadUserList.ashx,展示頁面里面可以用一個表格來展示了,首先我們在頁面前面引用jquery跟jquery-UI等需要用到的文件,再寫個table,具體如下:
<body>
<table id="userListTab">
<tr>
<th>編號
</th>
<th>登錄名
</th>
<th>電話
</th>
<th>郵箱
</th>
<th>操作
</th>
</tr>
</table><br /><!--頁面分頁 -->
<div id="pageNavigation"></div>
pageNavigation層用於放分頁導航.具體的后台代碼如下:
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
int pageSize = context.Request["pageSize"] == null ? 5 : int.Parse(context.Request["pageSize"]);
int pageIndex = context.Request["pageIndex"] == null ? 1 : int.Parse(context.Request["pageIndex"]);
int totalCount = 0;
totalCount = new BLL.HKSJ_USERS().GetRecordCount(string.Empty);
List<Model.HKSJ_USERS> users = new List<Model.HKSJ_USERS>();
DataSet ds = new BLL.HKSJ_USERS().GetListByPage(string.Empty, "Id", (pageIndex - 1) * pageSize + 1, pageIndex * pageSize);
users = new BLL.HKSJ_USERS().DataTableToList(ds.Tables[0]);
var pageNavigation = Common.LaomaPager.ShowPageNavigate(pageSize, pageIndex, totalCount);
var data = new { trData=users,pageNavigation };
string htmlString = new JavaScriptSerializer().Serialize(data);
context.Response.Write(htmlString);
}
當頁面加載的時候發送一個異步請求到后台,默認加載頁面時沒有context.request["pageSize"]跟["pageIndex"]這個參數的,我們默認顯示5個跟第1頁,后面是取得根據具體分頁等到的實體,我把他們放在list<model>中,方便后面序列化成json對象,然后根據pageSize跟pageIndex得到回傳回去具體的html代碼(就是一些a標簽),把pageNavigation and Users序列化Json對象,我直接用JavaScriptSerializer來序列化,當然你可以自己拼接字符串(比較靈活,就是比較麻煩,有很多轉義)...后台大致寫好了,下面開始寫前台的js代碼,我覺的我們一定要會調試js代碼,不然寫js代碼特別麻煩,不像vs寫C#代碼出錯各種提示,后面會說點我自己的調試的方法,寫js代碼要注意很多,我自己也寫的不熟,以后要多練練..好下面我們來寫前台的代碼..思路具體如下:
- 首先頁面加載發送個一個異步請求到后台,取得數據(json),在前台動態生成html標簽(也可以在后台拼接好了html再傳到前台,但是增加傳輸量,這就是我想把那個類改成js版的原因)
- 將生成的html代碼append到你所想展示的地方,我是展示到table里面,把這個兩個步驟封裝成一個方法function
- 加載數據算是完成,下面開始加載分頁導航,同樣頁面加載的時候發送一個請求到后台,這里我都請求同一個一般處理程序,因為返回的數據兩者都包含了.
- 下面要給分頁導航的a標簽注冊事件,並且不執行跳轉,同樣是也異步化的
具體代碼如下:
function InitUserListByPage(requestData) {
//每次加載先刪除再加載
$('#userListTab tr:gt(0)').remove();
//異步請求
$.getJSON("LoadUserList.ashx", requestData, function (data) {
for (i = 0; i < data.trData.length; i++) {
var htmlString = "<tr><td id='ID'>" + data.trData[i].ID + "</td><td id='LoginName'>" + data.trData[i].LoginName + "</td><td id='Phone'>" + data.trData[i].phone + "</td><td id='Mail'>" + data.trData[i].Mail + "</td><td><a href='DeleteUser.ashx?id=" + data.trData[i].ID + "' class='DeleteLink' userId=" + data.trData[i].ID + ">刪除</a></td><td><a href='UpdateUser.ashx?id=" + data.trData[i].ID + "' class='UpdateLink' userId=" + data.trData[i].ID + ">添加</a></td><tr>";
$('#userListTab').append(htmlString);
}
DeleUser();
Edituser();
});
}
function InitPageNavigation(requestData) {
$.getJSON("LoadUserList.ashx", requestData, function (data) {
var htmlString = data.pageNavigation;
$("#pageNavigation").html(htmlString);
$(".pageLink").click(function () {
var strHref = $(this).attr("href");
strHref = strHref.substring(strHref.lastIndexOf('?') + 1, strHref.length);
InitPageNavigation(strHref);
InitUserListByPage(strHref);
return false;
})
})
}
關於頁面分頁有些地方要說下:strHref是用來獲取發送到后台的參數:pageSize=1&pageIndex=5 這個字符串的,為超連接注冊事件,首先獲得所有的超鏈接(這個當前頁面沒有獲得,因為當前的頁面的class不是pageLink),點擊后我們要重新加載數據跟分頁,這里自己調用自己,聯合上面給出的加載數據的方法,是很容易理解的,也就是是重新獲取數據跟分頁.參數requsetData表示的是pageSize=1&pageIndex=5這個樣子的,如果沒有后台也做了處理默認給你第一頁跟5條數據,這一般加載的時候才傳個空數據.加載的代碼如下,直接調用兩個方法即可
$(function () {
//init table
$('#EditUser').css("display", "none");
InitUserListByPage();
//innit pagenavagation
InitPageNavigation();
這樣根據頁碼跟頁數得到數據,並且頁面不用跳轉:具體效果如下:不足之處在於點擊當前頁還是會刷新,這個很好解決,給當前也注冊事件就OK了~

刪除數據
下面所要做的操作就是刪除數據,這個就簡單了,發個一個異步請求到后台,刪除即可,我的做法就是在生成表格后加個刪除超鏈接,為超連接都加上個class="deleteLink"跟"UserID" =前面或者的ID,這樣就方便傳遞ID跟或者a標簽,需要注意的就是給a標簽注冊事件事件時必須在加載表格后再注冊,不然會失效的,同樣的我們封裝成一個方法function:
function DeleUser() {
$('.DeleteLink').click(function () {
var userId = $(this).attr("userId");
var td = $(this);
if (confirm("are you sure")) {
$.get("DeleteUser.ashx", { id: userId }, function (data) {
if (data = "true") {
td.parent().parent().hide("slow");
} else {
alert("Error");
}
});
}
return false;
});
}
一般刪除都需要有個確認,這里用confirm來確定,必須return false,后台代碼很簡單根據Id刪除就行了,返回true or false
添加數據
如同刪除一樣在后面加上添加超鏈接,並給超連接注冊事件,這里我是點擊,然后彈出個層來給用戶修改,上面展示數據,有個修改按鈕,並且給按鈕注冊事件,也就是給后台修改同樣是異步,彈出個遮罩層我直接用jquery-ui來了,自己寫也能寫,但又要寫一陀.剛開始的時候,我們首先讓修改層隱藏,點擊超鏈接,層出現,並把數據顯示出來,后台修改也要把原來的數據都查數來,因為有些數據是不會給用戶看的,更新的時候統統要更新的,后台代碼邏輯很簡單.
<!--修改層-->
<div id="EditUser">
<table>
<tr>
<td>編號</td>
<td>
<input type="hidden" name="hidden" value=" " id="hidden" />
<span id="txtShowId"></span></td>
<td>登錄名</td>
<td>
<input type="text" name="LoginNameShow" value=" " id="LoginNameShow" /></td>
<td>電話</td>
<td>
<input type="text" name="PhoneShow" value=" " id="PhoneShow" /></td>
<td>郵箱</td>
<td>
<input type="text" name="MailShow" value=" " id="MailShow" />
</td>
<td colspan="2">
<input type="button" name="Update" value="Update" id="Update" /></td>
</tr>
</table>
</div>
這里面需要個隱藏域來向后台傳遞ID,超鏈接的注冊事件如下:
//注冊添加用戶事件
function Edituser() {
$('.UpdateLink').click(function () {
var id = $(this).attr('userId');
$.getJSON("GetUserInfoById.ashx", { id: id }, function (data) {
$("#hidden").val(data.ID);
$("#txtShowId").text(data.ID);
$("#LoginNameShow").val(data.LoginName);
$("#MailShow").val(data.Mail);
$('#PhoneShow').val(data.phone);
})
//$("#hidden").val(id);
//$('#txtShowId').text(id);
$("#EditUser").dialog({//設置div為dialog
autoOpen: false,
title: "注冊用戶",
height: 400,
width: 1000,
modal: true
});
$("#EditUser").dialog("open");
return false;
})
}
這里顯示數據我是直接發個請求到后台根據ID或者數據,然后顯示到層上,下面就是給Update注冊事件了:
function UpdateUser() {
$('#Update').click(function () {
var JsonData = {
Id: $("#hidden").val(),
Phone: $('#PhoneShow').val(),
LoginName: $("#LoginNameShow").val(),
Mail: $("#MailShow").val()
}
$.get("UpdateUser.ashx", JsonData, function (data) {
if (data = "true") {
$("#EditUser").dialog("close");
InitUserListByPage();
}
})
})
}
具體效果如下:

其實添加一般都是用戶注冊的,我們可以不用一個隱藏的層,我們可以用一個iframe指向注冊頁面,點擊超鏈接,然后iframe顯示,用戶注冊.如果要用iframe指向一個寫好的頁面來實現無刷新效果的話,ifame不能操作父頁面的元素,這就帶來了不方便.我們一般是這樣父類提供一個屬性或者方法,你可以調用方法來更改父類的私有字段,這里我們在原頁面加入一個方法:
function afterRegistSuccess() {
$("#showRegistUser").dialog("close"); //彈出對話框
initUserTable();//綁定表格
}
iframe層為:
<!-----------------------彈出的添加用戶的對話框----------------------->
<div id="showRegistUser">
<iframe scrolling="yes" width="100%" height="100%" frameborder="0" src="RegistUser.htm"></iframe>
</div>
然后iframe指向頁面的代碼也要處理: window.parent.window指等就是我們父頁面,然后調用方法即可關閉層!
$.post("Regist.ashx", strRequestData, function (data) {
if (data == "ok") {
window.parent.window.afterRegistSuccess();
}
});
總結
寫js代碼一定要注意各種細節,其實邏輯不復雜,關鍵是有些地方少這個少那個,大小寫,能否取到ID等等,js好難調試.下面我說下我的調試方式,我一般使用chrome瀏覽器的開發人員工具來調,這樣可以看到很多東西,包括返回的json數據,請求報文返回報文等等,也可以調試JS代碼,寫JS不難調試難,個人感覺.就拿上面window.parent.window對象,我對這個很抽象,不知道寫的對不對,起初寫的window.parent,后來運行起來沒反應,我就用調試的過程加上個window才調出來,具體如下:

我先找的兩個對象..都是window...然后我再找誰有這個afterRegistSuccess方法,結果一看就知道.這個跟VS一樣可以設置斷點,右上的+號可以添加你想看得元素,如果你js代碼有錯誤,chrome也會幫你指出的,着實強大!總之我們要不僅僅要會寫更要出錯了知道哪里出錯,再改之.下面給出整個前台代碼 結合起來看更能理清自己的思路,后台的就不量出來了,就是crud,希望大家共同學習進步!
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>UserList</title>
<link href="http://www.cnblogs.com/style/tableStyle.css" rel="stylesheet" />
<link href="http://www.cnblogs.com/../Content/Css/ui-lightness/jquery-ui-1.8.4.custom.css" rel="stylesheet"
type="text/css" />
<script src="http://www.cnblogs.com/../js/jquery-1.4.2.min.js" type="text/javascript"></script>
<script src="http://www.cnblogs.com/../js/jquery-ui-1.8.4.custom.min.js"></script>
<script>
$(function () {
//init table
$('#EditUser').css("display", "none");
InitUserListByPage();
//innit pagenavagation
InitPageNavigation();
$('#Update').click(function () {
var JsonData = {
Id: $("#hidden").val(),
Phone: $('#PhoneShow').val(),
LoginName: $("#LoginNameShow").val(),
Mail: $("#MailShow").val()
}
$.get("UpdateUser.ashx", JsonData, function (data) {
if (data = "true") {
$("#EditUser").dialog("close");
InitUserListByPage();
}
})
})
});
//load userList
function InitUserListByPage(requestData) {
//每次加載先刪除再加載
$('#userListTab tr:gt(0)').remove();
//異步請求
$.getJSON("LoadUserList.ashx", requestData, function (data) {
for (i = 0; i < data.trData.length; i++) {
var htmlString = "<tr><td id='ID'>" + data.trData[i].ID + "</td><td id='LoginName'>" + data.trData[i].LoginName + "</td><td id='Phone'>" + data.trData[i].phone + "</td><td id='Mail'>" + data.trData[i].Mail + "</td><td><a href='DeleteUser.ashx?id=" + data.trData[i].ID + "' class='DeleteLink' userId=" + data.trData[i].ID + ">刪除</a></td><td><a href='UpdateUser.ashx?id=" + data.trData[i].ID + "' class='UpdateLink' userId=" + data.trData[i].ID + ">添加</a></td><tr>";
$('#userListTab').append(htmlString);
}
DeleUser();
Edituser();
});
}
//刪除用戶事件
function DeleUser() {
$('.DeleteLink').click(function () {
var userId = $(this).attr("userId");
var td = $(this);
if (confirm("are you sure")) {
$.get("DeleteUser.ashx", { id: userId }, function (data) {
if (data = "true") {
td.parent().parent().hide("slow");
} else {
alert("Error");
}
});
}
return false;
});
}
//頁面分頁
function InitPageNavigation(requestData) {
$.getJSON("LoadUserList.ashx", requestData, function (data) {
var htmlString = data.pageNavigation;
$("#pageNavigation").html(htmlString);
$(".pageLink").click(function () {
var strHref = $(this).attr("href");
strHref = strHref.substring(strHref.lastIndexOf('?') + 1, strHref.length);
InitPageNavigation(strHref);
InitUserListByPage(strHref);
return false;
})
})
}
//獲得分頁標簽
function pageNavigation(pageIndex, pageSize, totalCount) {
var redirectTo = "";
var totalPages = Math.max((totalCount + pageSize - 1) / pageSize, 1);
var pageNavi;
if (totalCount > 1) {
if (pageIndex != 1) {
pageNavi = "<a class='pageLink' href=" + redirectTo + "?pageIndex=1&pageSize=" + pageSize + "'>首頁</a> ";
} if (pageIndex > 1) {
pageNavi = "<a class='pageLink' href=" + redirectTo + "?pageIndex=" + pageIndex + "&pageSize=" + pageSize + "'>上一頁</a> ";
} else {
}
pageNavi = pageNavi + " ";
var currint = 5;
for (var i = 0; i < 10; i++) {
if ((pageIndex + i - currint) >= 1 && (pageIndex + i - currint) <= totalPages) {
if (currint == i) {
pageNavi = pageNavi + "<a class='cpb' href=" + redirectTo + "?pageIndex=" + pageIndex + "&pageSize=" + pageSize + "'>" + pageIndex + "</a> ";
} else {
pageNavi = pageNavi + "<a class='pageLink' href=" + redirectTo + "?pageIndex=" + pageIndex + i - currint + "&pageSize=" + pageSize + "'>" + pageIndex + i - currint + "</a> ";
}
}
pageNavi = pageNavi + " ";
if (pageIndex < totalPages) {
pageNavi = pageNavi + "<a class='pageLink' href=" + redirectTo + "?pageIndex=" + currentPage + 1 + "&pageSize=" + pageSize + "'>下一頁</a> "
} else {
}
pageNavi = pageNavi + " ";
if (pageIndex = totalPages) {
pageNavi = pageNavi + "<a class='pageLink' href=" + redirectTo + "?pageIndex=" + totalPages + "&pageSize=" + pageSize + "'>末頁</a> "
}
}
return pageNavi;
}
}
//注冊添加用戶事件
function Edituser() {
$('.UpdateLink').click(function () {
var id = $(this).attr('userId');
$.getJSON("GetUserInfoById.ashx", { id: id }, function (data) {
$("#hidden").val(data.ID);
$("#txtShowId").text(data.ID);
$("#LoginNameShow").val(data.LoginName);
$("#MailShow").val(data.Mail);
$('#PhoneShow').val(data.phone);
})
//$("#hidden").val(id);
//$('#txtShowId').text(id);
$("#EditUser").dialog({//設置div為dialog
autoOpen: false,
title: "注冊用戶",
height: 400,
width: 1000,
modal: true
});
$("#EditUser").dialog("open");
return false;
})
}
</script>
</head>
<body>
<table id="userListTab">
<tr>
<th>編號
</th>
<th>登錄名
</th>
<th>電話
</th>
<th>郵箱
</th>
<th>操作
</th>
</tr>
</table>
<br />
<!--頁面分頁 -->
<div id="pageNavigation">
</div>
<!--修改層-->
<div id="EditUser">
<table>
<tr>
<td>編號</td>
<td>
<input type="hidden" name="hidden" value=" " id="hidden" />
<span id="txtShowId"></span></td>
<td>登錄名</td>
<td>
<input type="text" name="LoginNameShow" value=" " id="LoginNameShow" /></td>
<td>電話</td>
<td>
<input type="text" name="PhoneShow" value=" " id="PhoneShow" /></td>
<td>郵箱</td>
<td>
<input type="text" name="MailShow" value=" " id="MailShow" />
</td>
<td colspan="2">
<input type="button" name="Update" value="Update" id="Update" /></td>
</tr>
</table>
</div>
</body>
</html>
