分頁列表框架
本章介紹很常用的分頁列表,詳情可查閱官方參考文檔中的”initPageList”函數介紹。
顯示單個列表
當列表預期可能很長時,一般應支持分頁。分頁列表在手機上的典型展現方式是支持上拉加載和下拉刷新。
[任務]
- 創建頁面orders2,仿照示例應用中訂單列表頁(orders)。本節先不按訂單狀態分欄,只顯示一個列表,支持上拉加載和下拉刷新。
- 點擊訂單列表中的一項,可以進入訂單詳情頁。
我們先熟悉一下支持分頁的列表查詢接口。
在示例應用自帶的模擬數據中,獲取訂單列表操作是支持分頁的,在瀏覽器控制檯上試試調用這些:
callSvrSync("Ordr.query");
// 返回 {nextkey: 20, list: [ {id: 147, dscr: "基礎套餐", status: "CR", ...}, ...(共20條)] }
// 取下一頁:上次返回的nextkey字段用於本次請求的_pagekey參數
callSvrSync("Ordr.query", {_pagekey: 20});
// 返回 {nextkey: 40, list: [ ...(共20條)] }
// 再取下一頁
callSvrSync("Ordr.query", {_pagekey: 40});
// 返回 {list: [ ...(共8條)] },沒有nextkey屬性,說明已是最後一頁。
默認每次返回20條數據,可以通過_pagesz
參數控制每次返回的數據條目數,如:
callSvrSync("Ordr.query", {_pagesz: 10});
// 返回 {nextkey: 10, list: [ ...(共10條)] }
我們使用這個模擬接口,新建頁面orders2:
HTML: (page/orders2.html)
<div mui-initfn="initPageOrders2" mui-script="orders2.js">
<div class="hd">
<a href="javascript:hd_back();" class="icon icon-back"></a>
<h2>分頁列表練習</h2>
</div>
<div class="bd">
<div id="lst1" data-ac="Ordr.query"></div>
</div>
</div>
在bd部分中,用一個div(id=lst1)作爲列表,用屬性”data-ac”指定了後端接口。
在頁面初始化函數initPageOrders2中,調用initPageList
函數初始化一個分頁列表:
JS: (page/orders2.js)
function initPageOrders2()
{
var jpage = this;
var listItf = initPageList(jpage, {
navRef: "",
listRef: "#lst1",
onAddItem: onAddItem,
onNoItem: onNoItem,
});
function onAddItem(jlst, itemData)
{
var ji = $("<div><b>" + itemData.dscr + "</b><p>訂單號: " + itemData.id + "</p></div>");
ji.appendTo(jlst);
// 把itemData存儲到事件中,可在事件回調中通過ev.data取到數據
ji.on("click", null, itemData, li_click);
}
function onNoItem(jlst)
{
var ji = $("<div>沒有訂單</div>");
ji.appendTo(jlst);
}
function li_click(ev)
{
var id = ev.data.id;
// 顯示訂單詳情頁
PageOrder.id = id;
MUI.showPage("#order");
}
}
函數initPageList封裝了接口交互的諸多細節,調用者只需要考慮如何展示列表項即可。
在參數中, listRef指定了列表組件的引用(只在當前邏輯頁上查找,相當於jpage.find(listRef)
),navRef指定導航欄,這裏未用到,賦值空就行,後面章節再介紹。
回調函數onAddItem用於添加一個列表項,onNoItem在列表爲空時調用,用於顯示沒有數據時的提示。
我們在首頁(page/home.html)中增加一個鏈接到頁面orders2:
<li class="weui_cell" style="display:block"><a href="#orders2" class="weui_btn weui_btn_primary">分頁列表練習</a></li>
進入頁面,可以看到向下拉動可以刷新列表(重新取第一頁數據),快到列表底部時可自動加載下一頁數據。
還有個常用的參數是onGetQueryParam,允許編程指定調用後端接口的參數,如:
var listItf = initPageList(jpage, {
...
// 設置查詢參數,靜態值一般通過在列表對象上設置屬性 data-ac, data-cond以及data-queryParam等屬性來指定更方便。
onGetQueryParam: function (jlst, queryParam) {
// 指定調用名,參數爲固定爲"ac"
queryParam.ac = "Ordr.query";
// 指定其它後端接口調用參數,比如頁大小,查詢條件,排序順序等
queryParam._pagesz = 10;
queryParam.orderby = "id desc";
}
}
例子中,由於是固定值,也可以在列表上通過屬性data-ac="Ordr.query" data-queryParam="orderby:'id desc', _pagesz:10"
來指定。
默認頁大小是20,由MUI.options.PAGE_SZ定義。
這裏有一點要注意:列表的容器(在本例中,#lst1
所在容器是.bd
)需要有確定的高度,且一般設置樣式”overflow-y: auto”,這樣列表才能滾動。
由於頁面的bd部分剛好會由框架自動設置高度,示例中沒有特別去設置,如果是自定義的容器,需要設置好高度。
(TODO:這個限制可能在未來被去掉)
[規約:外界對邏輯頁的操作使用邏輯頁接口]
上面在顯示訂單詳情頁時,用的方法是:
PageOrder.id = id;
MUI.showPage("#order");
我們把PageOrder
稱爲邏輯頁order的接口(page interface),在H5應用JS文件index.js中定義:
var PageOrder = {
// PageOrder.id
id: null,
};
在頁面order的JS邏輯中,會根據這裏的PageOrder.id顯示相應訂單。
儘管也可以通過全局變量等方式實現該功能(例如使用全局變量g_data.orderId),但不夠清晰,不建議使用。
外界對邏輯頁的操作,都應封裝到邏輯頁接口中。尤其不要在邏輯頁外直接設置該頁內的組件。
這樣,要查看哪些頁面引用了訂單頁,只要全局查找”PageOrder”即可。
這裏要顯示訂單,也可以這樣封裝:
var PageOrder = {
// PageOrder.show(id)
show: function (id) {
this.id_ = id;
MUI.showPage("#order");
},
id_: null
};
外面直接這樣調用:PageOrder.show(id)
. 把屬性”PageOrder.id”改名爲”PageOrder.id_”,暗示這個屬性由邏輯頁內部用,外界不應使用。