分頁列表框架(二)

天笑發表於2017-02-16

使用DOM模板建立元件

[任務]

上節練習中,函式onAddItem裡,直接使用了拼接html的方式動態建立列表項,當元件複雜時可讀性和可維護性很差。 我們將使用示例應用自帶的weui樣式庫美化列表項,並用DOM模板的方法重寫建立元件過程,讓程式碼更清晰。

一般情況下,不建議直接拼接html,而是通過模板及mvvm等技術來建立,這裡給大家推薦開源的超輕量的jquery-dataview庫,可在github中下載:

https://github.com/skyshore2001/jquery-dataview

或用這個git倉庫:http://dacatec.com/git/jquery-dataview.git。 下載後只需要jquery-dataview.min.js一個檔案即可,把它複製到server/lib目錄下,在H5應用index.html中引用:

<script src="lib/jquery-dataview.min.js"></script>

然後在頁面中定義列表項的模板,我們使用示例應用自帶的weui介面樣式庫:(page/orders2.html)

<div mui-initfn="initPageOrders2" mui-script="orders2.js">
    ...

    <div class="bd">
        <div id="lst1" class="weui_cells weui_cells_access" data-ac="Ordr.query"></div>
    </div>

<script id="tplOrder" type="text/template">
<div class="weui_cell" dv-on="li_click">
    <div class="weui_cell_hd">
        <i class="icon icon-dscr"></i>
    </div>
    <div class="weui_cell_bd weui_cell_primary">
        <p><b name="dscr"></b></p>
        <p>訂單號: <span name="id"></span></p>
    </div>
    <div class="weui_cell_ft" name="status"></div>
</div>
</script>

</div>

上例中:

  • 用script標籤定義了id為tplOrder的html模板,要動態賦值的地方用name="xxx"的方式標明,要處理事件的元件用dv-on屬性指定。 注意:H5標籤template在現階段的相容性還夠好,謹慎使用。
  • 使用weui樣式庫美化列表。在列表"lst1"上新增了"weui_cells"等CSS類, 在列表每一項上用了"weui_cell"類,詳細用法可查閱weui文件。
  • 列表每項前用<i class="icon icon-dscr"></i>放置了一個名為icon-dscr的圖示。

在JS中(page/orders2.js),我們重寫onAddItem函式,使用這個模板clone出每一項:

function initPageOrders2()
{
    var jpage = this;
    ...

    // 列表項模板
    var jtplOrder_ = $(jpage.find("#tplOrder").html());

    function onAddItem(jlst, itemData)
    {
        var ji = jtplOrder_.clone().dataview(itemData, {
            events: {
                li_click: li_click
            }
        }).appendTo(jlst);
    }

    ...
}

jquery-dataview在做事件繫結時,會自動將資料繫結到事件上。 例中,在li_click(ev)回撥函式中,可以通過ev.data拿到繫結的資料,因而剛好li_click函式不用修改,取訂單id可以用var id = ev.data.id

重新整理分頁列表

[任務]

控制重新整理分頁列表。

列表一旦顯示後,每次回到該邏輯頁時,不會重新請求資料或重新整理,除非使用者自己下拉重新整理列表,這樣保證了應用有良好的效能。

但有時需要在程式內控制列表重新整理,考慮這樣的需求:當一個訂單在其它頁面被修改了(例如取消訂單),再回到訂單列表頁時希望能重新整理列表。

initPageList可以很簡單地實現這一需求。 先為邏輯頁定義一個介面:

var PageOrders2 = {
    refresh: null,
}

在初始化列表時,新增一個pageItf選項(page interface縮寫):

    var listItf = initPageList(jpage, {
        pageItf: PageOrders2,
        ...
    });

在取消訂單操作時,只要賦值:

PageOrders2.refresh = true;

這樣下次進入orders2頁時,就會重新整理列表,並把PageOrders2.refresh置回false。可以在瀏覽器控制檯上操作試試看。

如果想要立刻重新整理列表,也可以用listItf.refresh()操作。 listItfinitPageList返回值,是一個操作列表的介面,類似的操作還有顯示下一頁listItf.loadMore(),詳見參考文件。

列表用於選擇

[任務]

(choose-from-list)在首頁上加一個“選擇訂單”按鈕,點選後進入訂單列表頁,選擇一項後返回首頁,並顯示訂單內容。

還是用"orders2"頁,我們在index.js中定義頁面介面如下(主要是choose方法和onChoose回撥):

var PageOrders2 = {
    ...
    // PageOrders2.choose(onChoose)
    // onChoose(order={id,dscr,...})
    choose: function (onChoose) {
        this.chooseOpt_ = {
            onChoose: onChoose
        }
        MUI.showPage('orders2');
    },

    chooseOpt_: null // {onChoose}
};

在頁面orders2中:

  • 點選一個列表項時,呼叫onChoose回撥
  • 頁面隱藏時,清空chooseOpt_引數。

示例:

function initPageOrders2()
{
    ...
    var pageItf_ = PageOrders2;
    jpage.on("pagehide", onPageHide);

    function li_click(ev)
    {
        var order = ev.data;
        if (pageItf_.chooseOpt_) {
            pageItf_.chooseOpt_.onChoose(order);
            return false;
        }

        // 正常點選操作 
        ...
    }

    function onPageHide()
    {
        pageItf_.chooseOpt_ = null;
    }
}

我們回到首頁,在瀏覽器控制檯中模擬呼叫:

PageOrders2.choose(function (order) {
    // 處理order
    app_alert('選擇了訂單: id=' + order.id);
    history.back(); // 由於進入列表選擇時會離開當前頁面,這時應返回
});

進入頁面orders,選擇一項後返回並繼續操作。

相關文章