Ajax初步认识

    最近在学习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代码要注意很多,我自己也写的不熟,以后要多练练..好下面我们来写前台的代码..思路具体如下:

  1. 首先页面加载发送个一个异步请求到后台,取得数据(json),在前台动态生成html标签(也可以在后台拼接好了html再传到前台,但是增加传输量,这就是我想把那个类改成js版的原因)
  2. 将生成的html代码append到你所想展示的地方,我是展示到table里面,把这个两个步骤封装成一个方法function
  3. 加载数据算是完成,下面开始加载分页导航,同样页面加载的时候发送一个请求到后台,这里我都请求同一个一般处理程序,因为返回的数据两者都包含了.
  4. 下面要给分页导航的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>

  

  

  源码下载

  

 

  

  

 

  

  

  

posted @ 2012-11-07 23:49  BigRocWings  阅读(3333)  评论(15编辑  收藏  举报