今天繼續WeX5的綁定機制。
需求分析
記賬本要實現的效果就是可以展示所有賬單,還能實時動態編輯每一筆賬單,官方案例的效果圖如下:
展示頁:
編輯頁
個人覺得官方案例加入了許多元素,不熟悉的同學每一個點都很難理解,所以為了更清晰地介紹綁定機制,小茄這里去掉了數據庫和數據組件,改用寫死的JSON數據來測試;UI層上也做簡化,去掉頁面片段的跳轉,使用一個頁面片
段進行演示。
頁面布局
先看看頁面布局,由於要展示多項數據,所以明顯需要一個列表組件;另外為了實現編輯功能,還需要布局一個編輯組件。布局起來非常簡單:
展示列表組件:
列表組件使用WeX5現成的 list 控件,這個控件內部自帶一個 list 子項的模板,在模板中放入所需的幾個 output 和刪除按鈕即可。當然,為了達到上圖的布局效果,還需要加入一些布局組件。有問題的同學可以看看官方視頻教
程,樣式的設置也請參考視頻,這不是本文的重點,在此不再贅述。
數據綁定
重要的一點是要將JSON數據綁定到list模板中,這里用的是foreach綁定,見下圖(當然也可以用template綁定+模板文件來實現,不過那樣的話還需要編寫模板文件,在自定義較強的場景下可以使用)。其他組件相應的綁定也如上圖所示,分別在各個 output 的 bind-ref 中輸入 fClass、fMoney等。
JS中給 accountData 一組靜態數據,實際應用中這些數據應該是從后台數據庫中獲取的。
1 var testData = [{ 2 fType : 'out', 3 fClass : '購物', 4 fMoney : 465, 5 fDate : '2015-05-24', 6 fDescription : '這是備注' 7 }, { 8 fType : 'out', 9 fClass : '餐費', 10 fMoney : 50, 11 fDate : '2015-10-22', 12 fDescription : '吃麻辣燙' 13 }, { 14 fType : 'in', 15 fClass : '獎金', 16 fMoney : 500, 17 fDate : '2015-10-22', 18 fDescription : '干得不錯' 19 }, { 20 fType : 'in', 21 fClass : '交通', 22 fMoney : 85, 23 fDate : '2015-10-22', 24 fDescription : '打了個車' 25 }]; 26 27 var Model = function() { 28 this.callParent(); 29 this.accountData = testData; 30 };
這時候打開瀏覽器調試可以看到JSON已經完整展現在頁面上。回顧一下上兩篇文章的內容,明顯上述寫法就是簡單的初始化,並沒有設置可觀察對象,也就是說數據變更也不會更新UI。下面來設置雙向綁定。
首先要明確的一點是,我們不單要監視 testData 數組的狀態變化,還需要監視每個JSON數據的變化,所以單純的設置數組為可監視對象是不夠的,還需要監視數組的值。這里需要改變一下寫法,不能再一次性賦值了,要改成構造
函數動態賦值。
1 function newItem(data) { 2 var testItem = { 3 fType : justep.Bind.observable(data.fType), 4 fClass : justep.Bind.observable(data.fClass), 5 fMoney : justep.Bind.observable(data.fMoney), 6 fDate : justep.Bind.observable(data.fDate), 7 fDescription : justep.Bind.observable(data.fDescription) 8 }; 9 return testItem; 10 } 11 12 var Model = function() { 13 this.callParent(); 14 this.accountData = justep.Bind.observableArray([]); 15 for (var n = 0, len = testData.length; n < len; n++) { 16 this.accountData.push(newItem(testData[n])); 17 } 18 };
這樣綁定之后,無論是改變數組(增減數組項)還是改變具體的數據都可以讓界面自動更新了。如果采用最開始的寫法,那是不會自動更新UI界面的。
上面的增加項已經是固定的,示范下而已,現在試着動態改變數據。先放效果:
相比官方的轉到一個獨立頁面的效果,這個效果更加的符合認知習慣,而且不用刷到另一頁,體驗更加友好,鼠標點哪改哪~
做法也很簡單,就是在output框下再接一個input框,設置output和input的 visible互斥,點擊事件更改visible狀態。HTML源碼片段是這樣的:
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 <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 Model.prototype.editBind = function(event){ 2 var row = event.bindingContext.$object; 3 row.editing.set(true); 4 }; 5
當然,editing 也必須要設置為可觀察對象,不然沒法更新UI展現。
1 function newItem(data) { 2 var testItem = { 3 fType : justep.Bind.observable(data.fType), 4 fClass : justep.Bind.observable(data.fClass), 5 fMoney : justep.Bind.observable(data.fMoney), 6 fDate : justep.Bind.observable(data.fDate), 7 fDescription : justep.Bind.observable(data.fDescription), 8 editing: justep.Bind.observable(data.editing || false) 9 }; 10 return testItem; 11 }
記賬本還要有個刪除功能,這個當然也是非常簡單了,直接操作可觀察對象數組即可,事件綁定在刪除按鈕上。
1 Model.prototype.deleteBtnClick = function(event) { 2 var row = event.bindingContext.$object; 3 this.accountData.remove(row); 4 };
還有個增加記錄,增加的操作就是先增加一條默認的數據,然后讓用戶去改動就變成新建啦,多加一個增加按鈕綁定增加事件即可。
1 Model.prototype.addItem = function(event){ 2 this.accountData.push(newItem({ 3 fType : 'in', 4 fClass : '獎金', 5 fMoney : 5000, 6 fDate : '2015-10-22', 7 fDescription : '干得不錯' 8 })); 9 };
這樣就算做好了一個記賬本啦,是不是感覺html5 APP開發很簡單呢??官方的教程使用了data組件與后台數據庫通信,其實也就是將上述的testData換成Data組件而已,理解了綁定再去看就簡單了。
哦,還有個美化的,根據收入支出分類以不同的顏色顯示:li 項的 bind-css 設置為 {'account-in' : fType.get() == 'in','account-out' : fType.get()== 'out'} 就OK了,上個圖:
Mapping 插件
大家可以看到上面為了將JSON對象中的每一項都設為可觀察對象,我這邊使用了一個 newItem 函數來將所有元素設置為可觀察對象,而Mapping 插件就是起同樣作用的。這里就不再舉例說明了,大家看官方視頻對照着用就可以了。
總結
這一篇以一個記賬本案例來總結了一下各種綁定的用法,希望能加深大家對綁定機制的理解。碼字不易,順手點贊哈~