今天整理1下WeX5的绑定机制。
原生的问题
假定我们做1个定单系统,需要显示商品单价,然后可以根据输入数量计算出总价并显示出来。使用原生代码也很容易实现,效果:
代码以下:
嗯,蛮简单的!哦,对了,我们1次展现50件商品,同时又有10类这样的展现,还有买5盒冈本送1根油条这样的各种促销呢……
所以,你知道原生实现的问题了吧:
WeX5的解决之道
为了解决上述问题,WeX5中引入了knockoutjs(下文简称ko)这个MVVM库。
为什么选用ko而不是Angular1类比较全面的框架?Angular是好,但这么大而全的框架,没有经过足够的实战测试的话,很多坑都不会被暴露出来。而ko是1个轻量级的MVVM库,专注于实现数据与视图的绑定,本身其实不提供 UI 类和路由等功能,所以非常简单稳定。同时,由于他出来也已有些年头了,现在是比较成熟的框架了。所以在做1些移动页面开发时,ko无疑是1个比较好的选择。另外,关于MVVM小茄就不多说了,1图以蔽之:
ko建立在3大核心特点之上(官网介绍):
1. 可视察对象与依赖跟踪 (Observables and dependency tracking):使用可视察对象在模型数据之间设立隐性关系链,用于数据转换和绑定。
2. 声明式绑定 (Declarative bindings):使用简单易读的语法方便地将模型数据与DOM元素绑定在1起。
3. 模板 (Templating):内置模板引擎、为你的模型数据快速编写复杂的 UI 展现。
下面简单说说ko的几大概念:
可视察对象
使用ko重写上面的例子(自定价格,这也是我小时候的欲望之1):
代码是这样的:
1)先看HTML代码:
可以看到在每一个标签中都加入了1个 data-bind = "XX:OO" 这样的键-值对。这个就是 ko 的绑定语法,XXOO代表甚么东西呢?(XXOO?小茄还是个孩子啊…)从例子可以看到XX为标签的属性,可以是text、value、class、checked等标签属性,其实也能够是click、focus、load等DOM事件。OO看起来像是1个变量,实际上其实不是变量,而是1个函数对象,履行这个函数(带个())就可以得到相应的绑定值。通过XXOO就能够将元素的属性或事件跟js中的函数对象绑定在1起(XXOO过了就要相互负责?),这就是ko的声明式绑定。绑定的定义其实就是1个视察者模式,只不过这是双向的绑定,发布者和定阅者相互定阅了对方的消息而已,这就是MVVM的双向绑定。ko双向绑定的结果就是1方变化就能够自动更新另外一方,也就是通过ViewModel将数据和表现层牢牢绑定在1起了。绑定的效果类似于:
2)再看看js代码:
可以看到js中定义了1个ViewModel对象,在对象中对HTML中绑定的OO进行了操作。这里主要有两个操作: ko.observable()和ko.pureComputed()。
定义好ViewModel构造函数后便实例化了1个ViewModel对象,然后使用了ko.applyBindings()的方式来使得绑定生效,这1步不要漏掉了。
使用ko的页面简单模式:
总结起来就是:HTML中使用data-bind="XX: OO"声明绑定,js中建立ViewModel并设置可视察对象,最后利用绑定。
可视察对象数组
再看看可视察对象数组的使用方法,在ko中可不能像js1样数组和变量混用,对数组对象就要用ko.observableArray([…,…])这类情势,一样的,数组元素也能够是基本类型也能够是json对象。ko中的可视察对象数组有1系列的数组操作方法,如slice()、sort()、push()这类,效果跟原生的js数组操作方法1样,只是通过ko方法所做的改动会通知到定阅者从而刷新界面,但js方法则不会刷新界面。下面是1个简单例子:
关键点:ko监控的是数组的状态,而不是元素本身的状态。也就是说当数组状态变化(增减元素)的时候会触发ko事件引发绑定对象的刷新,但数组内部元素的变化(如:值变化)则不被监控不能触发ko事件。例如:
在控制台中使用原生方法将Luffy动态改成Lucy是不会刷新UI页面的,而使用ko的数组操作改动数组则会立即刷新页面,值得注意的是在刷新的时候,也会将之前的改动刷新出来(Luffy > Lucy)。也就是说其实js内存中的变量是已改变了,但是还缺少1个刷新DOM的动作。这里大家可以看到,读取数组的方法是vm.list()[0],由于list也是1个函数对象,履行返回值才是我们想要的list内容。同理,也能够通过 vm.list(["妹子","妹子","妹子"]) 这样的方式重置可视察对象数组,也能立即刷新UI。
如果需要将数组元素的改动也动态反应到UI上,需要将数组元素也设置为可视察对象,然后使用ko的方法改变数组元素值。注意,是使用ko的方法 list()[0]("Lucy")!
操作可视察对象数组的方法有两类,1类是与原生js数组方法同名的:pop, push, shift, unshift, reverse, sort, splice,这1部份与js原生方法的用法和效果都1样,就不再赘述了。
另外1些方法是js中没有的,主要有以下几个:
小诀窍:在处理可视察对象时,若对象数量众多而且交互频繁的情况下,每次变更都立即刷新的话会非常消耗性能,这个时候可使用扩大 myObservableArray.extend({ rateLimit: 1000 }) 来设置延迟刷新。比如在不断往可视察对象数组中插入元素时,可以设置1个周期时间1000ms,让1000ms内的所有操作集中到1次刷新中去,避免频繁操作 DOM 带来的性能恶化。
WeX5中如何使用ko?
WeX5作为Html5 开发工具界的翘楚,少不了集成优秀的ko框架,使用的方法非常简单:在可视化编辑器中指定组件的bind属性,然后在js代码中操作相应绑定值。
先在可视化编辑器中指定:
这类方法在hello world篇也有简单介绍,不熟习的同学可以先去看看哈。通过可视化编辑器我们就能够绑定相应的属性或事件了,这里我们为 bind-ref 绑定了1个字符串“hello world”,至于其他的属性和事件将在下1篇中介绍。绑定后我们打开代码编辑器,发现里面并没有出现1)那样的绑定代码。那绑定代码写到哪里去了呢?请打开HTML源码:
可以看见代码中出现了“bind-ref='Hello World’”这个跟上文说的data-bind是否是很相似呢?这里WeX5将每一个组件可以绑定的属性都添加到可视化编辑器中,这样就不用再去记某个组件可以绑甚么属性了,鼠标指哪就绑哪!固然绑定字符串意义不大, 我们1般会绑定1个变量(实际上是返回值为所需变量的函数对象)。例如:
这里绑定了text为myText,这类情势的绑定为直接绑定在model对象下的,所以可以在js源码中的Model下操作这个myText对象。
1 define(function(require){ 2 var $ = require("jquery"); 3 var justep = require("$UI/system/lib/justep"); 4 5 var Model = function(){ 6 this.callParent(); 7 this.myText = justep.Bind.observable("bind!"); 8 }; 9 Model.prototype.button2Click = function(event){
10 this.myText.set("changed"); 11 }; 12 return Model; 13 }); 14
可以看到ko组件已被封装到justep的Bind对象里面去了,另外对可视察对象的操作也跟ko中有点不同,这里采取的是set/get分别来设置和获得可视察对象的值。其他诸如compute等大部份方法的用法跟ko中1致。
总结
本篇主要简单介绍了WeX5中数据绑定的由来和背后的优秀框架(knockoutjs),侧重介绍了ko中最重要的概念:可视察对象(数组),然后简单示范了如何在WeX5中使用绑定机制和 WeX5中的绑定与ko中的差异点。
关于可视察对象的简单介绍就到这里了,下1篇将具体介绍各种绑定的用法!码字不容易,随手点赞哈~
参考资料:
1. ko官方教程:http://knockoutjs.com/documentation/introduction.html
2. WeX5绑定教程:http://docs.wex5.com/data-bind-instro/
上一篇 动画效果(一)-渐变动画
下一篇 存储空间管理