使用 Extjs 做 Grid.Panel 分頁,一般來說會先將所有資料載到頁面,再做分頁,只是 Extjs 接收資料格式必須要在最根層加上總數量,這樣才能知道該頁顯示幾頁,總共有幾頁,所以格式必須符合如下:
{ "totalCount": "6679", "topics": [ { // .... }, { // .... }, { // .... }, { // .... }, { // .... } // ... ] }
而符合這種格式必須在 Web Api 段做些許調整,要多寫一個屬性讓 API 能使用,可以參考:Web API, OData, $inlinecount and testing,程式碼如下
public class InlineCountQueryableAttribute : QueryableAttribute { private static MethodInfo _createPageResult = typeof(InlineCountQueryableAttribute) .GetMethods(BindingFlags.Static | BindingFlags.NonPublic) .Single(m => m.Name == "CreatePageResult"); public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { base.OnActionExecuted(actionExecutedContext); HttpRequestMessage request = actionExecutedContext.Request; HttpResponseMessage response = actionExecutedContext.Response; IQueryable result; if (response.IsSuccessStatusCode && response.TryGetContentValue<IQueryable>(out result)) { long? inlineCount = request.GetInlineCount(); if (inlineCount != null) { actionExecutedContext.Response = _createPageResult.MakeGenericMethod(result.ElementType).Invoke( null, new object[] { request, request.GetInlineCount(), request.GetNextPageLink(), result }) as HttpResponseMessage; } } } internal static HttpResponseMessage CreatePageResult<T>(HttpRequestMessage request, long? count, Uri nextpageLink, IEnumerable<T> results) { return request.CreateResponse(HttpStatusCode.OK, new PageResult<T>(results, nextpageLink, count)); } }
在 API 加上此屬性:
[InlineCountQueryable] public IEnumerableGetEmployees() { IEnumerable employees = db.Employees.ToList(); foreach (Employees employee in employees) { employee.Employees1 = null; employee.Employees2 = null; } return employees; }
執行結果如下:
{ Count: 15, Items: [ { ... }, { ... }, ... ], NextPageLink: XXX, }
這樣輸出結果與 Extjs Grid.Panel 做分頁要接收的格式已經 95% 相似了,而換頁時通常自動會帶 page 、 start 和 limit,page 感覺只是顯示用,而 start 和 limit 的部分可以使用 API 的 Queryable 來解決,它等同於 Queryable 的 $skip 和 $top:
首先我們先看如何在 grid.Panel 加上分頁,加上一個屬性即可,其中 store 為資料來源:
bbar: Ext.create('Ext.PagingToolbar', { store: store, displayInfo: true, displayMsg: 'Displaying topics {0} - {1} of {2}', emptyMsg: "No topics to display", }),
因為每一次換頁就會與 store 要一次資料,所以必須針對來源做修改:
var store = Ext.create('Ext.data.JsonStore', { storeId: 'store', model: 'Model', pageSize: 3, proxy: { type: 'ajax', url: 'http://localhost:8090/api/Control?$inlinecount=allpages', reader: { type: 'json', root: 'Items', totalProperty: 'Count', }, startParam: '$skip', limitParam: '$top' }, autoLoad: true, listeners: { load: function (store, records, options) { } }, });
其中 PageSize 為每頁顯示數量,而 startParam、limitParam 則是改變它換頁帶的參數,最後執行就可以看到每換一次頁就會重新與 API 要一次資料,這樣一來頁面負擔不會太重,同時又做到速度與流量兼顧的結果。
沒有留言 :
張貼留言