今天整理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/
上一篇 動畫效果(一)-漸變動畫
下一篇 存儲空間管理