接續上一篇「ASP.NET MVC 資料分頁 MVCPaging 2.0 應用 Part.1:一般、表單(Form)」,這一篇將會說明如何使用 MvcPaging 的 Ajax.Pager 方式來完成 AJAX 分頁的功能。
一開始就先做個基本分頁的方式,先不考慮表單 POST 資料傳送的問題,我們以 MvcPaging.Demo 的 IndexAjax 頁來做為參考範本,參考裡面的作法,
MvcPaging.Demo 的網站專案的下載位置:https://github.com/martijnboland/MvcPaging
先來看看 MvcPaging.Demo 的 Controller 與 ViewPage 的程式內容,
ViewPage > IndexAjax.cshtml
PartialView > _ProductGrid.cshtml
而在 PartialView 中的 Html.Pager() 詳細設定設定內容如下:
@Html.Pager(Model.PageSize, Model.PageNumber, Model.TotalItemCount, new AjaxOptions { UpdateTargetId = "gridcontainer"}).Options(o => o.Action("AjaxPage"))
其中 AjaxOptions 的設定是使用了 System.Web.Mvc.Ajax.AjaxOptions,所以這邊會需要指定一個要更換內容的容器 ID,然後再後面的 Options() 中要去指定在 Controller 中處理分頁內容的 Action 方法。
因為是使用了 System.Web.Mvc.Ajax,所以記得要在 ViewPage 上加入 jquery.unobtrusive-ajax.js 檔案的引用,像 MvcPaging.Demo 則是在 _Layout.cshtml 中加入「jquery.unobtrusive-ajax.min.js」的使用,
記得一定要加入,不然是 MvcPaging 的 Html.Pager() 是無法有 Ajax 的效果。
另外 ASP.NET MVC 使用 AjaxHelper 上需要注意一些設定的地方,可以參考下面的這篇 KKBruce 所寫的文章,
KKBruce:ASP.NET MVC 2與MVC 3使用AJAXHELPER引用JAVASCRIPT檔不同
Controller > IndexAjax, AjaxPage
MvcPaging.Demo 的 Ajax 分頁做法就是把要分頁處理的 Pager 與表格內容給抽出來放在 PartialView 檔案裡,點選分頁連結後將分頁碼送回到後端 Controller 的 AjaxPage,AjaxPage 取出分頁資料後,將分頁資料使用 PartialView 送回到前端,前端接收到後端所傳回來的分頁內容後,再去替換掉 ID 為「gridcontainer」的內容,如此就完成 AJAX 分頁的功能。
實作
我們看完 MvcPaging.Demo 的範例之後,再回來看我們要用來做 AJAX 分頁的網頁,資料呈現的頁面是沿用「ASP.NET MVC 資料分頁 MVCPaging 2.0 應用 Part.1:一般、表單(Form)」的 DefaultPage 頁,
點選 Pager 的分頁連結後所需要更換的內容是下圖紅線所框起來的部分,這個紅線所框起來的部分就要抽出來另外做為 PartialView 內容,而其他的內容則還是留在原來的主頁面中,
先處理表單內容的前端事件處理,這邊要做 AJAX 處理,所以原本表單的 submit POST 就需要做另外的處理,改使用 jQuery 的 AJAX 來處理表單資料 POST 的動作,因為是要修改為 AJAX,當表單送出並取得資料後,有時候使用者去變動表單中的下拉選單所選擇的值,然後又去點選分頁連結,而造成表單值與顯示結果不一致,所以當表單送出之後就會將下拉選單做 disable 的處理;
另外連帶要做修改的就是 reset 的部份,因為 submit 表單資料後會 disable 下拉選單,所以 reset 的事件處理就是解除下拉選單的 disable 以及將下拉選單的選取狀態設為預設值,另外還要做的就是清空 gridcontainer 的內容,以下的這段 jQuery 程式內容是放在 DefaultPageAjax.cshtml 當中,
@if (false){ <script src="../../Scripts/jquery-1.7.2.min.js" type="text/javascript"></script> }<script type="text/javascript">
<!--$(document).ready(function () {$('#ButtonSubmit').click(function () { ButtonSubmitEventHandler(); });
$('#ButtonReset').click(function () { ButtonResetEventHandler(); });
});function ButtonSubmitEventHandler() {
var cityValue = $('#city option:selected').val();
var columnValue = $('#sortColumnName option:selected').val();
var sortValue = $('#sort option:selected').val();
$.ajax({url: '@Url.Action("DefaultPageAjaxPartial", "Home")',data: { city: cityValue, sortColumnName: columnValue, sort: sortValue },type: 'post',async: false,
cache: false,
dataType: 'html',success: function (data) {
$('#gridcontainer').html(data);$('#city').attr('disabled', true);
$('#sortColumnName').attr('disabled', true);
$('#sort').attr('disabled', true);
}});}function ButtonResetEventHandler() {
$('#city option:eq(0)').attr('selected', true);
$('#sortColumnName option:eq(0)').attr('selected', true);
$('#sort option:eq(0)').attr('selected', true)
$('#city').removeAttr('disabled');$('#sortColumnName').removeAttr('disabled');$('#sort').removeAttr('disabled');$('#gridcontainer').empty();}--></script>
DefaultPageAjax.cshtml
因為沒有在 _Layout.cshtml 去加入「jquery.unobtrusive-ajax.min.js」,所以就直接在 DefaultPageAjax.cshtml 中加入,
@model IPagedList<MvcMSSQL.Models.Customer>@{ViewBag.Title = "DefaultPageAjax";Layout = "~/Views/Shared/_Layout.cshtml";}<script type="text/javascript" src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")"></script><h2>DefaultPageAjax</h2><fieldset><br />City:@Html.Raw(ViewData["CityDDL"].ToString())Sort ColumnName:@Html.Raw(ViewData["ColumnDDL"].ToString())Sort Type:@Html.Raw(ViewData["SortDDL"].ToString())<input type="button" value="submit" id="ButtonSubmit" /><input type="button" value="Reset" id="ButtonReset" /></fieldset><div id="gridcontainer">@Html.Partial("DefaultPageAjaxPartial", Model)</div>
接下來再看 PartialView「DefaultPageAjaxPartial.cshtml」的內容,在 PartialView「DefaultPageAjaxPartial.cshtml」這邊要特別注意的就是 Html.Pager() 的設定,
<div class="pager">@Html.Pager(Model.PageSize, Model.PageNumber, Model.TotalItemCount, new AjaxOptions { UpdateTargetId = "gridcontainer" }).Options(o => o.Action("DefaultPageAjaxPartial").AddRouteValue("city", ViewBag.City).AddRouteValue("sortColumnName", ViewBag.SortColumnName).AddRouteValue("sort", ViewBag.Sort))Displaying @Model.ItemStart - @Model.ItemEnd of @Model.TotalItemCount item(s)</div>
要去增加 AjaxOptions 的內容,並且指定 AJAX 要做更換的容器 ID,然後在 Options 中加入後端 PartialView 的處理 Action 方法名稱,還有增加 RouteValue 設定,增加 RouteValue 設定值,這樣在做 AJAX 分頁時一樣可以維持表單裡下拉選單的選取條件。
最後貼上 Controller 裡的 Action() 程式內容:
private const int DefaultPageSize = 5;private IList<Customer> allCustomers = new List<Customer>();public ActionResult DefaultPageAjax()
{int currentPageIndex = 0;
this.PrepareDropDownLists(this.FilterCity, this.SortColumnName, this.SortType);ViewBag.City = this.FilterCity;
ViewBag.SortColumnName = this.SortColumnName;
ViewBag.Sort = this.SortType;
ViewData.Model = this.allCustomers.ToPagedList(currentPageIndex, DefaultPageSize);
return View();
}public ActionResult DefaultPageAjaxPartial(int? page,string city = "all",string sortColumnName = "CustomerID",string sort = "asc"){int currentPageIndex = page.HasValue ? page.Value - 1 : 0;
this.FilterCity = city;
this.SortColumnName = sortColumnName;
this.SortType = sort;
ViewBag.City = city;ViewBag.SortColumnName = sortColumnName;ViewBag.Sort = sort;using (NorthwindEntities db = new NorthwindEntities()){var query = db.Customers.Select(x => x);if (!city.Equals("all")){query = query.Where("City == @0", city ?? "London");}query = query.OrderBy(string.Format("{0} {1}", sortColumnName, sort));ViewData.Model = query.ToPagedList(currentPageIndex, DefaultPageSize);return PartialView("DefaultPageAjaxPartial");}}
執行結果:
初始頁面
按下 submit 後,表單的下拉選單都 disable 並於下方顯示 Pager 與資料內容
顯示其他分頁
點選 reset 以清除分頁內容
調整表單的下拉選單選取值後送出,
顯示其他分頁
這邊觀察有關資料傳送的內容,當點選一個分頁連結後,傳送到後端的資料內容如下:
而後端傳回到前端的內容如下:
可以看到這個 PartialView 的內容是 Pager 與 Table 的原始碼,
HTML 內容
操作影片
下回再來說明如何使用 jQuery 來達成 AJAX 分頁的功能……
以上
沒有留言:
張貼留言