今天繼續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 插件就是起同樣作用的。這里就不再舉例說明了,大家看官方視頻對照著用就可以了。
總結
這一篇以一個記賬本案例來總結了一下各種綁定的用法,希望能加深大家對綁定機制的理解。碼字不易,順手點贊哈~