起步软件技术论坛
搜索
 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 2595|回复: 1

[分享] 【分享】WeX5的正确打开方式(5)——绑定机制

  [复制链接]

13

主题

28

帖子

388

积分

中级会员

Rank: 3Rank: 3

积分
388
QQ
发表于 2016-7-4 14:26:50 | 显示全部楼层 |阅读模式
本帖最后由 小太阳 于 2016-7-4 14:41 编辑

  
今天继续WeX5的绑定机制。

需求分析

记账本要实现的效果就是可以展示所有账单,还能实时动态编辑每一笔账单,官方案例的效果图如下:
展示页:
   1.jpg
编辑页
    2.jpg

    个人觉得官方案例加入了许多元素,不熟悉的同学每一个点都很难理解,所以为了更清晰地介绍绑定机制,小茄这里去掉了数据库和数据组件,改用写死的JSON数据来测试;UI层上也做简化,去掉页面片段的跳转,使用一个页面片
段进行演示。

页面布局

    先看看页面布局,由于要展示多项数据,所以明显需要一个列表组件;另外为了实现编辑功能,还需要布局一个编辑组件。布局起来非常简单:
展示列表组件:
    3.jpg
    列表组件使用WeX5现成的 list 控件,这个控件内部自带一个 list 子项的模板,在模板中放入所需的几个 output 和删除按钮即可。当然,为了达到上图的布局效果,还需要加入一些布局组件。有问题的同学可以看看官方视频教
程,样式的设置也请参考视频,这不是本文的重点,在此不再赘述。

数据绑定

    重要的一点是要将JSON数据绑定到list模板中,这里用的是foreach绑定,见下图(当然也可以用template绑定+模板文件来实现,不过那样的话还需要编写模板文件,在自定义较强的场景下可以使用)。其他组件相应的绑定也如上
图所示,分别在各个 output 的 bind-ref 中输入 fClass、fMoney等。
    4.jpg

    JS中给 accountData 一组静态数据,实际应用中这些数据应该是从后台数据库中获取的。
  
  1. 1 var testData = [{
  2.   2     fType : 'out',
  3.   3     fClass : '购物',
  4.   4     fMoney : 465,
  5.   5     fDate : '2015-05-24',
  6.   6     fDescription : '这是备注'
  7.   7 }, {
  8.   8     fType : 'out',
  9.   9     fClass : '餐费',
  10. 10     fMoney : 50,
  11. 11     fDate : '2015-10-22',
  12. 12     fDescription : '吃麻辣烫'
  13. 13 }, {
  14. 14     fType : 'in',
  15. 15     fClass : '奖金',
  16. 16     fMoney : 500,
  17. 17     fDate : '2015-10-22',
  18. 18     fDescription : '干得不错'
  19. 19 }, {
  20. 20     fType : 'in',
  21. 21     fClass : '交通',
  22. 22     fMoney : 85,
  23. 23     fDate : '2015-10-22',
  24. 24     fDescription : '打了个车'
  25. 25 }];
  26. 26
  27. 27 var Model = function() {
  28. 28     this.callParent();
  29. 29     this.accountData = testData;
  30. 30 };
复制代码

    这时候打开浏览器调试可以看到JSON已经完整展现在页面上。回顾一下上两篇文章的内容,明显上述写法就是简单的初始化,并没有设置可观察对象,也就是说数据变更也不会更新UI。下面来设置双向绑定。
    首先要明确的一点是,我们不单要监视 testData 数组的状态变化,还需要监视每个JSON数据的变化,所以单纯的设置数组为可监视对象是不够的,还需要监视数组的值。这里需要改变一下写法,不能再一次性赋值了,要改成构造函数动态赋值。
  
  1. 1 function newItem(data) {
  2.   2     var testItem = {
  3.   3         fType : justep.Bind.observable(data.fType),
  4.   4         fClass : justep.Bind.observable(data.fClass),
  5.   5         fMoney : justep.Bind.observable(data.fMoney),
  6.   6         fDate : justep.Bind.observable(data.fDate),
  7.   7         fDescription : justep.Bind.observable(data.fDescription)
  8.   8     };
  9.   9     return testItem;
  10. 10 }
  11. 11
  12. 12 var Model = function() {
  13. 13     this.callParent();
  14. 14     this.accountData = justep.Bind.observableArray([]);
  15. 15     for (var n = 0, len = testData.length; n < len; n++) {
  16. 16         this.accountData.push(newItem(testData[n]));
  17. 17     }
  18. 18 };
复制代码

    这样绑定之后,无论是改变数组(增减数组项)还是改变具体的数据都可以让界面自动更新了。如果采用最开始的写法,那是不会自动更新UI界面的。
    5.gif
    上面的增加项已经是固定的,示范下而已,现在试着动态改变数据。先放效果:
    6.gif
  相比官方的转到一个独立页面的效果,这个效果更加的符合认知习惯,而且不用刷到另一页,体验更加友好,鼠标点哪改哪~
    做法也很简单,就是在output框下再接一个input框,设置output和input的 visible互斥,点击事件更改visible状态。HTML源码片段是这样的:
  
  1. 1 <div component="$UI/system/components/justep/output/output" class="x-output h3" xid="output2" bind-visible="!editing.get()" bind-ref="fClass" bind-click="editBind" />
  2.   2 <input component="$UI/system/components/justep/input/input" class="form-control h3" xid="input1" bind-visible="editing" bind-value="fClass" bind-hasFocus="editing"/>
复制代码


    js 里面就一句:
  
  1. 1 Model.prototype.editBind = function(event){
  2.   2     var row = event.bindingContext.$object;
  3.   3     row.editing.set(true);
  4.   4 };
  5.   5
复制代码


    当然,editing 也必须要设置为可观察对象,不然没法更新UI展现。

  1.   1 function newItem(data) {
  2.   2     var testItem = {
  3.   3         fType : justep.Bind.observable(data.fType),
  4.   4         fClass : justep.Bind.observable(data.fClass),
  5.   5         fMoney : justep.Bind.observable(data.fMoney),
  6.   6         fDate : justep.Bind.observable(data.fDate),
  7.   7         fDescription : justep.Bind.observable(data.fDescription),
  8.   8         editing: justep.Bind.observable(data.editing || false)
  9.   9     };
  10.   10     return testItem;
  11.   11 }
复制代码

    记账本还要有个删除功能,这个当然也是非常简单了,直接操作可观察对象数组即可,事件绑定在删除按钮上。
  
  1. 1 Model.prototype.deleteBtnClick = function(event) {
  2.   2     var row = event.bindingContext.$object;
  3.   3     this.accountData.remove(row);
  4.   4 };
复制代码


    还有个增加记录,增加的操作就是先增加一条默认的数据,然后让用户去改动就变成新建啦,多加一个增加按钮绑定增加事件即可。
  
  1. 1 Model.prototype.addItem = function(event){
  2.   2     this.accountData.push(newItem({
  3.   3         fType : 'in',
  4.   4         fClass : '奖金',
  5.   5         fMoney : 5000,
  6.   6         fDate : '2015-10-22',
  7.   7         fDescription : '干得不错'
  8.   8     }));
  9.   9 };
复制代码


    这样就算做好了一个记账本啦,是不是感觉html5 APP开发很简单呢??官方的教程使用了data组件与后台数据库通信,其实也就是将上述的testData换成Data组件而已,理解了绑定再去看就简单了。
     哦,还有个美化的,根据收入支出分类以不同的颜色显示:li 项的 bind-css 设置为 {'account-in' : fType.get() == 'in','account-out' : fType.get()== 'out'} 就OK了,上个图:
   7.gif

Mapping 插件

    大家可以看到上面为了将JSON对象中的每一项都设为可观察对象,我这边使用了一个 newItem 函数来将所有元素设置为可观察对象,而Mapping 插件就是起同样作用的。这里就不再举例说明了,大家看官方视频对照着用就可以了。
总结
这一篇以一个记账本案例来总结了一下各种绑定的用法,希望能加深大家对绑定机制的理解。码字不易,顺手点赞哈~


评分

参与人数 1威望 +100 收起 理由
liangyongfei + 100 很给力!

查看全部评分

30

主题

114

帖子

1044

积分

金牌会员

Rank: 6Rank: 6

积分
1044
QQ
发表于 2016-12-20 23:32:33 | 显示全部楼层
牛!!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|X3技术论坛|Justep Inc.    

GMT+8, 2024-11-22 12:59 , Processed in 0.119595 second(s), 30 queries .

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表