前言
发现大家对于我从 json 文件中直接操作节点属性来控制界面的动态变化感到比较好奇,所以这篇就针对数据绑定以及如何使用这些绑定的数据做一篇说明,我写了一个简单的例子,基于机房工控的服务器上设备的灯闪烁现象。我们从 2d 和 3d 两个角度来分析数据绑定的问题。
效果图
2d 3d
代码实现
其实不管是 2d 还是 3d,在 HT 中,数据绑定不分维度的,所以两者在实现上非常类似。
代码下载地址:https://download.csdn.net/download/u013161495/10290996
绘制设备
2d 和 3d 中的设备都是基于下面这张用“矢量”绘制的一个机柜内部设备,并且对这个矢量的“闪烁灯”部分加了数据绑定,具体绑定了“闪烁灯”的背景颜色以及阴影颜色,改变阴影颜色是为了让“灯”有“发光”的效果,下图中的红色方框即为“闪烁灯”。
首先我们必须清楚如何绘制矢量(http://hightopo.com/guide/guide/core/vector/ht-vector-guide.html)?我们这个 Demo 的整体的矢量绘制比较复杂,我就只说一下上图中的“灯”矩形框和文本是怎么绘制的。
我们知道,绘制一个矢量 json 必须包含以下三个参数:
- width 矢量图形的宽度
- height 矢量图形的高度
- comps 矢量图形的组件 Array 数组,每个数组对象为一个独立的组件类型(http://hightopo.com/guide/guide/core/vector/ht-vector-guide.html#ref_type),数组的顺序为组件绘制先后顺序
每个元素肯定都是要宽度和高度的,这两个属性不做说明,comps 这个属性倒是挺厉害的,上面第三点中提到了,这是一个数组,绘制图形和文本的实际操作如下:
{ "width": 48,//矢量整体宽度 "height": 262,//矢量整体高度 "comps": [ { "type": "text",//文本 "text": "端口3",//文本内容 "align": "center",//文本对齐方式 "color": "rgb(255,255,255)",//字体颜色 "font": "8px arial, sans-serif",//文本字体大小 "rect": [//组件绘制在矢量中的矩形边界 18.28654,//x 轴坐标 39.80679,//y 轴坐标 27.82265,//width 11.5434//height ] }, { "type": "rect",//矩形 "background": "rgb(255,0,0)",//属性默认值"shadow": true,//设置为true显示阴影"shadowOffsetX": 0,//选中图元的阴影水平偏移 "shadowOffsetY": 0,//选中图元的阴影垂直偏移 "rect": [//组件绘制在矢量中的矩形边界 4.38544,//x 轴坐标 32.55505,//y 轴坐标 14.46481,//width 6.1554//height ] }] }
这段代码绘制了一个矩形和一个文本。
绘制完矢量之后,我们就可以通过给节点设置图片的方式来显示这个矢量。当然上面绘制的矢量并不是全部的绘制矢量的代码,具体内容请参考:https://download.csdn.net/download/u013161495/10290996。
要动态改变一个节点的属性,那么肯定要先获取到这个节点,我们可以通过遍历数据模型 DataModel,或者通过 tag 标签获取节点,又或者通过鼠标点击事件等等。这个 Demo 中需要操作的节点比较多,所以我选择用遍历数据模型的方法来获取节点。那么问题来了,我怎么通过一张图片或者一个矢量定位这个节点?如果节点都没有创建,也不可能获取到图片对应的节点(或者说如果直接把这个矢量图拿来作为一个节点的图片,有可能出现的情况就是,六个设备的变化情况都一模一样!毕竟是同一个节点!)。所以我们得把这些特殊的部分从图片中删除掉,然后在对应的位置填充上节点,再给节点设置上设备的矢量图。先把对应位置的矢量图删除掉,如下图红框部分:
我们在红框部分单独创建八个设备节点,并给这八个节点分别设置同一张矢量图。诶?你可能会诧异为什么同一张图显示却不同(灯亮的变化顺序不同),下面我们来看看这是怎么完成的。
那么这八个拥有相同矢量图的设备是如何通过代码控制闪烁灯随机变化的呢?关键就在我们上面绘制的矢量图中,前面有意略过了这部分:数据绑定。
数据绑定
由于灯闪烁是通过设置矩形的背景颜色来实现的(当然我这里还加了一个阴影,为了有“亮灯”的效果),所以我们对这个矩形的背景颜色属性进行数据绑定,然后通过 data.a 方法获取和设置属性值。
{ "type": "rect",//矩形 "background": {//矩形背景 "func": "attr@rectBg2",//数据绑定string类型若以attr@***开头,则返回data.getAttr(***)值,其中***代表attr的属性名 "value": "rgb(255,0,0)"//属性默认值 }, "shadow": true,//设置为true显示阴影 "shadowColor": {//阴影颜色 "func": "attr@shadowColor2",//数据绑定string类型 "value": "rgba(255,0,0,0.35)"//属性默认值 }, "shadowOffsetX": 0,//选中图元的阴影水平偏移 "shadowOffsetY": 0,//选中图元的阴影垂直偏移 "rect": [//组件绘制在矢量中的矩形边界 4.38544,//x 轴坐标 32.55505,//y 轴坐标 14.46481,//width 6.1554//height ] }
上面是我对矩形灯矢量的部分重新绘制后的代码,看出什么不同了?对,background 属性和 shadowColor 属性都出现了两个值,并且这两个值看起来“怪怪的”?数据绑定(http://hightopo.com/guide/guide/core/databinding/ht-databinding-guide.html)没有那么难,绑定的格式很简单,只需将以前的参数值用一个带 func 属性的对象替换即可,如果对应的 func 取得的值为 undefined 或 null 时,则会采用 value 属性定义的默认值。
func 的内容有以下几种类型:
- function 类型,直接调用该函数,并传入相关 Data 和 view 对象,由函数返回值决定参数值,即 func(data, view) 调用。
- string 类型:
- style@*** 开头,则返回 data.getStyle(***) 值,其中 *** 代表 style 的属性名。
- attr@*** 开头,则返回 data.getAttr(***) 值,其中 *** 代表 attr 的属性名。
- field@*** 开头,则返回 data.*** 值,其中 *** 代表 data 的属性名。
- 如果不匹配以上情况,则直接将 string 类型作为 data 对象的函数名调用 data.***(view),返回值作为参数值。
所以我们通过 "func" 来绑定数据,这里用的是 attr@*** 的方式绑定,到时候要调用这个属性的时候就直接通过 data.getAttr(***) 或者缩写 data.a(***) ;然后通过 "value" 设置一个默认值,作为 func 返回的值为空时的“备用”。
一般我们将代码比较多的矢量图放在一个 json 文件中,我取名叫做 service3d.json 放在 scene 文件夹下 ,通过 ht.Default.xhrLoad 方法解析 json 文件的内容,如下:
ht.Default.xhrLoad('scene/service3d.json', function(text) { var json = ht.Default.parse(text); dm.deserialize(json);//反序列化 })
其中 deserialize 反序列化函数是将数据反序列化到模型,传入的参数 json 为数据信息对象,用于解析生成对应的 Data 对象并添加到数据容器中。
因为 xhrLoad 方法是异步加载,为了避免后面出现获取不到数据的问题,我们将剩下的节点属性控制代码也写在 xhrLoad 函数中:
dm.each(function(data) {//遍历dataModel var infos = [//我设置的业务属性名称 {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数组 data.a(info.shadowColor, 'rgba(255, 0, 0, 0.35)');//注册业务属性 attr 为业务属性 简写为 a data.a(info.background, 'rgb(255, 0, 0)'); }); setInterval(function() {//设置动画 动态变化闪烁灯的亮和灭的显示 var random = Math.ceil(Math.random() * 5);//获取5以内一个随机整数 (可以配合我设置的业务属性名称) 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)');//设置为绿色透明 } else if(data.a(shadowName) === 'rgba(0, 255, 0, 0.35)') {//如果是绿色透明 data.a(shadowName, 'rgba(255, 0, 0, 0.35)');//设置为红色透明 } if(data.a(bgName) === 'rgb(255, 0, 0)') {//如果是红色 data.a(bgName, 'rgb(0, 255, 0)');//设置为绿色 } else if(data.a(bgName) === 'rgb(0, 255, 0)') {//如果是绿色 data.a(bgName, 'rgb(255, 0, 0)');//设置为红色 } }, 1000); });
值得注意的一点是,虽然我们在 json 中已经绑定了业务属性(这里是“shadowColor1,2,3,4,5...”和“rectBg1,2,3,4,5”),但是节点上并没有这个属性,所以我们需要注册一下这些属性,并给这些属性设置属性值。
然后我们就可以通过调用这些属性来动态更新 Data 上的属性值图形界面就会自动刷新,从而达到实时显示数据的效果。因为 HT 只有一个数据模型,绑定 DataModel 的图形组件并没有组件内部的其他数据模型,所以组件都是如实根据 DataModel 来呈现界面效果,因此当用户拖拽图元移动时, 本质也是修改了数据模型中 Node 的 position 位置值,而该属性变化触发的事件通过模型再次派发到图形组件,引发图形组件根据新的模型信息刷新界面。
总结
其实数据绑定没有什么很深奥的部分,HT 也不需要你考虑太多,一切以最简单的方式进行着。这个 Demo 需要注意的就是,相同的图片,如果要显示不同,那么肯定需要创建不同的节点,若是节点相同,那么变化肯定相同的!
相关推荐
**Android数据绑定(DataBinding)**是Android开发中的一个强大的库,它允许开发者在XML布局文件中直接绑定UI元素和数据模型,极大地简化了视图和数据之间的交互,减少了代码的冗余,提高了应用的可维护性和可读性。...
C#中的数据绑定(DataBinding)是.NET框架提供的一种强大机制,它允许用户界面(UI)元素与数据源之间建立动态连接,使UI能够自动反映出数据源的变化。数据绑定简化了应用程序开发,尤其是在构建用户界面时,使得...
Android开发:10.DataBinding数据绑定技术解析.pdf
在Android开发中,DataBinding库是一种强大的工具,它可以帮助开发者更方便地管理视图与数据模型之间的绑定,从而简化代码并提高可读性。本文将深入探讨DataBinding库中的事件绑定功能,帮助你理解如何利用这一特性...
在Android开发中,DataBinding库是Google推出的一种官方数据绑定框架,它可以帮助开发者更方便地实现视图与数据模型之间的绑定,从而简化UI逻辑,提高代码的可读性和可维护性。本文将深入探讨DataBinding的基本用法...
Android DataBinding库是Google推出的一种数据绑定框架,它旨在简化Android应用中的UI绑定,特别是对于MVVM(Model-View-ViewModel)设计模式的实现。双向绑定是DataBinding库的一个核心特性,它允许视图(View)和...
在IT领域,尤其是在软件开发与编程中,数据绑定(Data Binding)是一项关键技能,它能够极大地提高应用程序的灵活性...无论是对于初学者还是有经验的开发者,深入学习和实践数据绑定都是提升C#应用开发效率的重要途径。
数据绑定简化了数据驱动的应用程序开发,因为它减少了手动更新UI和数据源之间状态的代码量。 在C#中,数据绑定通常涉及到以下步骤: 1. **定义数据源**:数据源可以是任何实现了INotifyPropertyChanged接口的对象,...
Android DataBinding 的官方双向绑定示例展示了如何使用双向绑定来同步数据和用户界面,并且提供了自定义双向绑定的方法。开发者可以使用这些技术来快速构建用户界面,并且减少代码量和开发时间。
Android DataBinding是Google推出的一种强大的数据绑定库,它旨在简化Android应用中的UI逻辑,通过将视图和数据模型直接关联起来,减少代码量并提高可读性。在本篇文章中,我们将深入探讨如何使用这个框架。 一、...
在Android开发中,Data Binding Library是一种强大的工具,它允许开发者将UI组件与数据源直接绑定,简化了MVVM(Model-View-ViewModel)架构中的代码,提高了可读性和可维护性。在这个“DataBinding Demo绑定...
里面是我对DataBinding的总结,有相应的注释适合学习,希望多提建议,互相学习互相进步。文章:http://blog.csdn.net/weiwozhiyi/article/details/52181532
在Android开发中,数据绑定(Data Binding)是一个强大的框架,它允许开发者将界面UI元素直接绑定到应用的数据源,从而简化了代码,提高了可读性和维护性。本示例将详细解析如何在Android项目中使用Data Binding库,...
1. jetpet组合使用,包含: 1). 使用MVVM模式设计,拆分...简单的一个Jetpet组合,简明易懂,能学会使用方式,怎么绑定视图,怎么调用方法,怎么保存数据,监控数据变更并实时更新UI,以及DataBinding的一些语句样式。
.NET 窗体应用程序开发中,数据绑定(DataBinding)是一项有用的技术,这个Demo中用到了简单绑定和数据库绑定,可以看到在使用了数据绑定后,将操作与显示关联起来,不用去手工处理显示的细节,很方便。
数据绑定控件在Windows Forms和WPF(Windows Presentation Foundation)等平台上广泛使用,简化了用户界面的开发和维护。本主题将深入探讨如何在C#中利用数据绑定控件进行数据录入。 1. 数据源:在C#中,数据源可以...
Databinding提供了一种更简洁、可维护的方式来绑定数据到UI元素,而RecyclerView则是一个高效的数据展示控件,适用于大量的列表或网格数据。本篇文章将深入探讨如何将这两者完美结合,以提升应用的用户体验和代码...
本文将深入探讨“双向绑定”这一核心概念,并结合MVVM和Databinding来阐述其在实际开发中的应用。 首先,我们要理解MVVM架构的基本原理。MVVM是由微软在WPF框架中引入的一种设计模式,它将模型(Model)、视图...
在Android开发中,DataBinding库是一种强大的工具,它简化了视图与数据模型之间的绑定,提高了代码的可读性和可维护性。在这个“DataBinding实现RecyclerView的Demo”中,我们将探讨如何利用DataBinding来优雅地处理...