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; width: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下載地址


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM