使用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()
操作。
listItf
是initPageList
返回值,是一個操作列表的接口,類似的操作還有顯示下一頁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,選擇一項後返回並繼續操作。