zoukankan      html  css  js  c++  java
  • ASP.NET MVC分页 Ajax+JsRender

    前段时间整mvc的分页,倒是很顺利,参考了以下几篇博客,启发很大。

    http://www.cnblogs.com/tangmingjun/archive/2012/05/30/2526301.html

    http://www.cnblogs.com/tangmingjun/archive/2012/05/31/2528732.html

    顺便扩展了需求,在分页的基础上,继续做关键字查询。

    用PagedList生成的页码链接虽然样式很漂亮,但是要做到无刷新的分页,PagedList自动生成的代码是不够用的,可以配合jsRender和Ajax做上面的效果,同时手动构建PagedList生成的页码标签,根据自己的需要设置href和onclick事件。

    直接上代码

    前台:

    @{
        ViewBag.Title = "Index";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
    
    <h2>商品信息</h2>
    
    <p>
        @Html.ActionLink("新建", "Create") |
        @Html.Editor("txtSearch")
        <input type="button" value="查找" id="btnSearch" />
        <img id="imgWaiting" src="~/Images/loading.gif" style="display:none; 30px; height:30px;" />
    </p>
    <table class="table">
        <thead>
            <tr>
                <th>商品名称</th>
                <th>商品描述</th>
                <th>原价</th>
                <th>特价(现价)</th>
                <th>销量</th>
                <th>修改日期</th>
                <th>商品链接</th>
                <th>状态</th>
                <th>图片</th>
                <th></th>
            </tr>
        </thead>
        <tbody id="tblContent"></tbody>
    </table>
    <div id="divPage"></div>
    
    <script type="text/x-jsrender" id="contentTemplate">
        <tr>
            <td>{{:GoodName}}</td>
            <td>{{:Description}}</td>
            <td>{{:OriginalPrice}}</td>
            <td>{{:SpecialPrice}}</td>
            <td>{{:Sales}}</td>
            <td>{{:ActiveTime}}</td>
            <td>{{:Url}}</td>
            <td>{{:Status}}</td>
            <td>{{:PicPath}}@*<img id="PicPath" src="{{:PicPath}}" class="thumbnailPdt" />*@</td>
            <td>
                <a href="/Admin/Goods/Edit/{{:GoodID}}">Edit</a> |
                <a href="/Admin/Goods/Delete/{{:GoodID}}">Delete</a>
            </td>
        </tr>
    </script>
    
    @section  Scripts{
        <script src="~/Scripts/jsrender.min.js" type="text/javascript"></script>
        <script>
            var key = "";
            function doSearch(page) {
                key = $("#txtSearch").val();
                $.post(
                     "/Admin/Goods/SearchProduct",
                    { keyword: key, pageNo: page },
                    function (data, status) {
                        //数据写到前台
                        $("#tblContent").html($("#contentTemplate").render(data.contents));
                        $("#divPage").html(data["pageList"]);
                    },
                "json"
                );
            };
            //绑定点击查询事件
            $("#btnSearch").click(function () {
                doSearch(1);
            });
            //输入框回车开始查询
            $("#txtFilter").bind("keypress", function () {
                if (event.keyCode == 13) { $("#btnSearch").click(); return false; }
            });
            //加载初始化数据
            $(function () {
                doSearch(1);
            });
        </script>
    }
    View Code

    后台Controller:

    public ActionResult Index()
    {
        return View();
    }
    
    public JsonResult SearchProduct(string keyword, int? pageNo)
    {
        int pageIndex = pageNo ?? 1;
        int totalCount;
        var goods = GetSearchData(keyword, ref pageIndex, _PageSize, out totalCount);
        int totalPage = totalCount / _PageSize + (totalCount % _PageSize == 0 ? 0 : 1);
        var pagerHtml = ExHtml.CreatePagesHtml(totalPage, pageIndex);
    
        return Json(new { contents = goods, pageList = pagerHtml }, JsonRequestBehavior.DenyGet);
    }
    
    List<Good> GetSearchData(string keyword, ref int pageIndex, int pageSize, out int totalCount)
    {
        var linq = from p in db.Goods select p;
        if (!string.IsNullOrWhiteSpace(keyword))
        {
            linq = linq.Where(t =>
                t.GoodID.ToString() == keyword
                || t.GoodName.Contains(keyword)
                || t.Description.Contains(keyword)
                );
        }
        totalCount = linq.Count();
        //修正pageIndex
        var maxPage = totalCount / pageSize + (totalCount % pageSize == 0 ? 0 : 1);
        if (pageIndex < 1) pageIndex = 1;
        if (pageIndex > maxPage) pageIndex = maxPage;
        linq = linq.OrderByDescending(x => x.GoodID)
                .Skip((pageIndex - 1) * pageSize)
                .Take(pageSize);
    
        return linq.ToList();
    }
    View Code

    扩展函数:

    public static string CreatePagesHtml(int totalPageNo, int currPageNo, string jsClickName = "doSearch")
    {
        if (currPageNo > totalPageNo || currPageNo < 1 || totalPageNo == 1) return "";
        string res = "";
        if (currPageNo > 3) res += LiForFirst(jsClickName);//有跳转到第一页
        //if (currPageNo > 2) res += LiForPrev(currPageNo - 1, jsClickName);//跳转到前一页
        if (currPageNo > 4) res += LiForOthers();//无跳转,显示中间有页面
        if (currPageNo > 2) res += LiForPage(currPageNo - 2, jsClickName);//前两页
        if (currPageNo > 1) res += LiForPage(currPageNo - 1, jsClickName);//前一页
    
        res += LiForCurr(currPageNo);//当前页
    
        if (currPageNo < totalPageNo) res += LiForPage(currPageNo + 1, jsClickName);//下一页
        if (currPageNo < totalPageNo - 1) res += LiForPage(currPageNo + 2, jsClickName);//下两页
        if (currPageNo < totalPageNo - 3) res += LiForOthers();//无跳转,显示中间有页面
        //if (currPageNo < totalPageNo - 1) res += LiForNext(currPageNo + 1, jsClickName);//跳转到后一页
        if (currPageNo < totalPageNo - 2) res += LiForLast(totalPageNo, jsClickName);//跳转到最后页
        return string.Format(@"
        <div class=""pagination-container"">
            <ul class=""pagination"">
                {0}
            </ul>
        </div>"
            , res);
    }
    static string GetPageItem(int pageNo, string text, string jsClickName, string classStr = null, string rel = null)
    {
        return string.Format(@"<li{0}><a href=""#""{1}{2}>{3}</a></li>"
            , string.IsNullOrWhiteSpace(classStr) ? "" : " class="" + classStr + """
            , string.IsNullOrWhiteSpace(rel) ? "" : " rel="" + rel + """
            , string.IsNullOrWhiteSpace(jsClickName) ? "" : string.Format(" onclick="{0}({1});"", jsClickName, pageNo)
            , text
            );
    }
    static string LiForFirst(string jsClickName) { return GetPageItem(1, "1"/*"««"*/, jsClickName, classStr: "PagedList-skipToFirst"); }
    static string LiForPrev(int pageNo, string jsClickName) { return GetPageItem(pageNo, "«", jsClickName, classStr: "PagedList-skipToPrevious", rel: "prev"); }
    static string LiForNext(int pageNo, string jsClickName) { return GetPageItem(pageNo, "»", jsClickName, classStr: "PagedList-skipToNext", rel: "next"); }
    static string LiForLast(int totalPageNo, string jsClickName) { return GetPageItem(totalPageNo, totalPageNo.ToString()/*"»»"*/, jsClickName, classStr: "PagedList-skipToLast"); }
    static string LiForPage(int pageNo, string jsClickName) { return GetPageItem(pageNo, pageNo.ToString(), jsClickName); }
    static string LiForCurr(int pageNo) { return GetPageItem(pageNo, pageNo.ToString(), null, classStr: "active"); }
    static string LiForOthers() { return GetPageItem(0, "&#8230;", null, classStr: "disabled PagedList-ellipses"); }
    View Code

    前台的关键代码是js函数doSearch,通过post发送请求,请求成功后处理返回的json数据,并重新加载页面部分元素。json数据包有两个属性,一个contents,里面是类型为List<T>的数据,通过jsrender的调用,生成前台表格的tbody中的代码;另一个pageList是后台组装好的,显示page按钮的string。

    后台Controller代码中,主要是第二个函数SearchProduct,它可以作为一个controller下面的action调用,在里面执行查询数据,以及组装pageHtml的操作,并打包这些数据成json数据,返回给前台。

    扩展函数代码则主要是组装page的string结果。这部分参考PagedList生成的页码标签的代码,样式在bootstrap里面都有。

    环境:VS2013 + MVC5.0 + Bootstrap 3.0

    JsRender下载地址

  • 相关阅读:
    优化网站设计系列文章总结和导读
    jQuery插件实现select下拉框左右选择_交换内容(multiselect2side)
    php代码生成二维码
    微信公众平台开发(83) 生成带参数二维码
    MySQL主从问题
    mysql配置文件my.cnf
    网站UV,与IP、PV
    git基础使用小记
    系统运维
    [译]Profile and debug your ASP.NET MVC app with Glimpse
  • 原文地址:https://www.cnblogs.com/icyJ/p/JsRender.html
Copyright © 2011-2022 走看看