• 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,
                         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,
                         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>
    

      

      

      源码下载

      

     

      

      

     

      

      

      

  • 相关阅读:
    Delphi中的接口和抽象类
    设计模式之六大原则
    C 标准库
    linux 管道和重定向
    linux c创建静态库(.a)
    一个C语言程序
    C#动态创建lambda表达式
    linq中order by 和group by (含lambda表达式实现)以及综合案例
    微信扫码登陆原理
    二维码扫码支付原理
  • 原文地址:https://www.cnblogs.com/wings/p/2759691.html
Copyright © 2020-2023  润新知