變臉式應用 / 分頁列表框架

分頁列表框架

本章介紹很常用的分頁列表,詳情可查閱官方參考文檔中的”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_”,暗示這個屬性由邏輯頁內部用,外界不應使用。

發佈了65 篇原創文章 · 獲贊 16 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章