快速开发基于 HTML5 网络拓扑图应用之 DataBinding 数据绑定篇
前言
發(fā)現(xiàn)大家對于我從 json 文件中直接操作節(jié)點屬性來控制界面的動態(tài)變化感到比較好奇,所以這篇就針對數(shù)據(jù)綁定以及如何使用這些綁定的數(shù)據(jù)做一篇說明,我寫了一個簡單的例子,基于機房工控的服務(wù)器上設(shè)備的燈閃爍現(xiàn)象。我們從 2d 和 3d 兩個角度來分析數(shù)據(jù)綁定的問題。
效果圖
2d
代碼實現(xiàn)
其實不管是 2d 還是 3d,在 HT 中,數(shù)據(jù)綁定不分維度的,所以兩者在實現(xiàn)上非常類似。
代碼下載地址:https://download.csdn.net/download/u013161495/10290996
繪制設(shè)備
2d 和 3d 中的設(shè)備都是基于下面這張用“矢量”繪制的一個機柜內(nèi)部設(shè)備,并且對這個矢量的“閃爍燈”部分加了數(shù)據(jù)綁定,具體綁定了“閃爍燈”的背景顏色以及陰影顏色,改變陰影顏色是為了讓“燈”有“發(fā)光”的效果,下圖中的紅色方框即為“閃爍燈”。
首先我們必須清楚如何繪制矢量(http://hightopo.com/guide/guide/core/vector/ht-vector-guide.html)?我們這個 Demo 的整體的矢量繪制比較復(fù)雜,我就只說一下上圖中的“燈”矩形框和文本是怎么繪制的。
我們知道,繪制一個矢量 json 必須包含以下三個參數(shù):
- width 矢量圖形的寬度
- height 矢量圖形的高度
- comps 矢量圖形的組件 Array 數(shù)組,每個數(shù)組對象為一個獨立的組件類型(http://hightopo.com/guide/guide/core/vector/ht-vector-guide.html#ref_type),數(shù)組的順序為組件繪制先后順序 每個元素肯定都是要寬度和高度的,這兩個屬性不做說明,comps 這個屬性倒是挺厲害的,上面第三點中提到了,這是一個數(shù)組,繪制圖形和文本的實際操作如下:
這段代碼繪制了一個矩形和一個文本。
繪制完矢量之后,我們就可以通過給節(jié)點設(shè)置圖片的方式來顯示這個矢量。當然上面繪制的矢量并不是全部的繪制矢量的代碼,具體內(nèi)容請參考:download.csdn.net/download/u0…
要動態(tài)改變一個節(jié)點的屬性,那么肯定要先獲取到這個節(jié)點,我們可以通過遍歷數(shù)據(jù)模型 DataModel,或者通過 tag 標簽獲取節(jié)點,又或者通過鼠標點擊事件等等。這個 Demo 中需要操作的節(jié)點比較多,所以我選擇用遍歷數(shù)據(jù)模型的方法來獲取節(jié)點。那么問題來了,我怎么通過一張圖片或者一個矢量定位這個節(jié)點?如果節(jié)點都沒有創(chuàng)建,也不可能獲取到圖片對應(yīng)的節(jié)點(或者說如果直接把這個矢量圖拿來作為一個節(jié)點的圖片,有可能出現(xiàn)的情況就是,六個設(shè)備的變化情況都一模一樣!畢竟是同一個節(jié)點!)。所以我們得把這些特殊的部分從圖片中刪除掉,然后在對應(yīng)的位置填充上節(jié)點,再給節(jié)點設(shè)置上設(shè)備的矢量圖。先把對應(yīng)位置的矢量圖刪除掉,如下圖紅框部分:
我們在紅框部分單獨創(chuàng)建八個設(shè)備節(jié)點,并給這八個節(jié)點分別設(shè)置同一張矢量圖。誒?你可能會詫異為什么同一張圖顯示卻不同(燈亮的變化順序不同),下面我們來看看這是怎么完成的。
那么這八個擁有相同矢量圖的設(shè)備是如何通過代碼控制閃爍燈隨機變化的呢?關(guān)鍵就在我們上面繪制的矢量圖中,前面有意略過了這部分:數(shù)據(jù)綁定。
數(shù)據(jù)綁定
由于燈閃爍是通過設(shè)置矩形的背景顏色來實現(xiàn)的(當然我這里還加了一個陰影,為了有“亮燈”的效果),所以我們對這個矩形的背景顏色屬性進行數(shù)據(jù)綁定,然后通過 data.a 方法獲取和設(shè)置屬性值。
{"type": "rect",//矩形"background": {//矩形背景"func": "attr@rectBg2",//數(shù)據(jù)綁定string類型若以attr@***開頭,則返回data.getAttr(***)值,其中***代表attr的屬性名"value": "rgb(255,0,0)"//屬性默認值},"shadow": true,//設(shè)置為true顯示陰影"shadowColor": {//陰影顏色"func": "attr@shadowColor2",//數(shù)據(jù)綁定string類型"value": "rgba(255,0,0,0.35)"//屬性默認值},"shadowOffsetX": 0,//選中圖元的陰影水平偏移"shadowOffsetY": 0,//選中圖元的陰影垂直偏移"rect": [//組件繪制在矢量中的矩形邊界4.38544,//x 軸坐標32.55505,//y 軸坐標14.46481,//width6.1554//height] } 復(fù)制代碼上面是我對矩形燈矢量的部分重新繪制后的代碼,看出什么不同了?對,background 屬性和 shadowColor 屬性都出現(xiàn)了兩個值,并且這兩個值看起來“怪怪的”?數(shù)據(jù)綁定(http://hightopo.com/guide/guide/core/databinding/ht-databinding-guide.html)沒有那么難,綁定的格式很簡單,只需將以前的參數(shù)值用一個帶 func 屬性的對象替換即可,如果對應(yīng)的 func 取得的值為 undefined 或 null 時,則會采用 value 屬性定義的默認值。
func 的內(nèi)容有以下幾種類型:
- function 類型,直接調(diào)用該函數(shù),并傳入相關(guān) Data 和 view 對象,由函數(shù)返回值決定參數(shù)值,即 func(data, view) 調(diào)用。
- string 類型:
- style@*** 開頭,則返回 data.getStyle(***) 值,其中 *** 代表 style 的屬性名。
- attr@*** 開頭,則返回 data.getAttr(***) 值,其中 *** 代表 attr 的屬性名。
- field@*** 開頭,則返回 data.*** 值,其中 *** 代表 data 的屬性名。
- 如果不匹配以上情況,則直接將 string 類型作為 data 對象的函數(shù)名調(diào)用 data.***(view),返回值作為參數(shù)值。
所以我們通過 "func" 來綁定數(shù)據(jù),這里用的是 attr@*** 的方式綁定,到時候要調(diào)用這個屬性的時候就直接通過 data.getAttr(***) 或者縮寫 data.a(***) ;然后通過 "value" 設(shè)置一個默認值,作為 func 返回的值為空時的“備用”。
一般我們將代碼比較多的矢量圖放在一個 json 文件中,我取名叫做 service3d.json 放在 scene 文件夾下 ,通過 ht.Default.xhrLoad 方法解析 json 文件的內(nèi)容,如下:
ht.Default.xhrLoad('scene/service3d.json', function(text) {var json = ht.Default.parse(text);dm.deserialize(json);//反序列化 }) 復(fù)制代碼其中 deserialize 反序列化函數(shù)是將數(shù)據(jù)反序列化到模型,傳入的參數(shù) json 為數(shù)據(jù)信息對象,用于解析生成對應(yīng)的 Data 對象并添加到數(shù)據(jù)容器中。
因為 xhrLoad 方法是異步加載,為了避免后面出現(xiàn)獲取不到數(shù)據(jù)的問題,我們將剩下的節(jié)點屬性控制代碼也寫在 xhrLoad 函數(shù)中:
dm.each(function(data) {//遍歷dataModelvar infos = [//我設(shè)置的業(yè)務(wù)屬性名稱{shadowColor: 'shadowColor1', background: 'rectBg1'},{shadowColor: 'shadowColor2', background: 'rectBg2'},{shadowColor: 'shadowColor3', background: 'rectBg3'},{shadowColor: 'shadowColor4', background: 'rectBg4'},{shadowColor: 'shadowColor5', background: 'rectBg5'},];infos.forEach(function(info) {//遍歷infos數(shù)組data.a(info.shadowColor, 'rgba(255, 0, 0, 0.35)');//注冊業(yè)務(wù)屬性 attr 為業(yè)務(wù)屬性 簡寫為 adata.a(info.background, 'rgb(255, 0, 0)');});setInterval(function() {//設(shè)置動畫 動態(tài)變化閃爍燈的亮和滅的顯示var random = Math.ceil(Math.random() * 5);//獲取5以內(nèi)一個隨機整數(shù) (可以配合我設(shè)置的業(yè)務(wù)屬性名稱)var shadowName = 'shadowColor' + random,bgName = 'rectBg' + random;if(data.a(shadowName) === 'rgba(255, 0, 0, 0.35)') {//如果是紅色透明data.a(shadowName, 'rgba(0, 255, 0, 0.35)');//設(shè)置為綠色透明}else if(data.a(shadowName) === 'rgba(0, 255, 0, 0.35)') {//如果是綠色透明data.a(shadowName, 'rgba(255, 0, 0, 0.35)');//設(shè)置為紅色透明}if(data.a(bgName) === 'rgb(255, 0, 0)') {//如果是紅色data.a(bgName, 'rgb(0, 255, 0)');//設(shè)置為綠色}else if(data.a(bgName) === 'rgb(0, 255, 0)') {//如果是綠色data.a(bgName, 'rgb(255, 0, 0)');//設(shè)置為紅色}}, 1000);}); 復(fù)制代碼值得注意的一點是,雖然我們在 json 中已經(jīng)綁定了業(yè)務(wù)屬性(這里是“shadowColor1,2,3,4,5...”和“rectBg1,2,3,4,5”),但是節(jié)點上并沒有這個屬性,所以我們需要注冊一下這些屬性,并給這些屬性設(shè)置屬性值。
然后我們就可以通過調(diào)用這些屬性來動態(tài)更新 Data 上的屬性值圖形界面就會自動刷新,從而達到實時顯示數(shù)據(jù)的效果。因為 HT 只有一個數(shù)據(jù)模型,綁定 DataModel 的圖形組件并沒有組件內(nèi)部的其他數(shù)據(jù)模型,所以組件都是如實根據(jù) DataModel 來呈現(xiàn)界面效果,因此當用戶拖拽圖元移動時, 本質(zhì)也是修改了數(shù)據(jù)模型中 Node 的 position 位置值,而該屬性變化觸發(fā)的事件通過模型再次派發(fā)到圖形組件,引發(fā)圖形組件根據(jù)新的模型信息刷新界面。
總結(jié)
其實數(shù)據(jù)綁定沒有什么很深奧的部分,HT 也不需要你考慮太多,一切以最簡單的方式進行著。這個 Demo 需要注意的就是,相同的圖片,如果要顯示不同,那么肯定需要創(chuàng)建不同的節(jié)點,若是節(jié)點相同,那么變化肯定相同的!
總結(jié)
以上是生活随笔為你收集整理的快速开发基于 HTML5 网络拓扑图应用之 DataBinding 数据绑定篇的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 20165105第三周学习总结
- 下一篇: jmeter之关联操作