变脸式应用 / 分页列表框架(二)

使用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,选择一项后返回并继续操作。

发布了65 篇原创文章 · 获赞 16 · 访问量 8万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章