1. 代码界面 VS 组态界面
1.1 代码API创建界面
1.2 组态拖拽生成界面
2. 代码界面显示到组态
以应用平台代码为例,步骤如下
2.1 原始示例js代码
HTML |
2.2 复制到平台应用并微调
- 修改相对路径的资源文件为了便于观察关键效果
- 将实例化的new ht.DataModel()换成this.dm2d()
- 将实例化的new ht.graph.GraphView()换成this.g2d()
- 屏蔽掉document.body.appendChild、window.addEventListener相关代码
- init()启动加到合适位置主动调用
JavaScript |
运行效果
3. 组态图纸与代码界面混合
3.1 组态图纸上最好勾选“事件处理”,保证鼠标交互事件传递到代码创建的组件中
3.2 拖放图标到组态图纸中
3.3 微调代码错开拖放的界面和代码创建的界面位置避免重叠
JavaScript |
运行效果
4. * 图纸拖放的图元对象传给并替换代码中实例化new的对象
从前面1~3我们知道,代码创建的界面,是完全可以给到组态图纸拖拽框架去展示的,无非就是dataModel、graphView本身是代码中new实例化对象,改成应用平台中获取组态图纸的dm2d和g2d对象替换过去即可(当然对于dm3d和g3d也一样)。同时去掉代码中document.body.appendChild()、window.addEventListener等对浏览器dom的全局操作,因为组态框架已经做了这些。
还有个问题,那就是代码中创建的图元比如ht.Node、ht.Data、ht.Grid等这些视图及其数据模型对应的数据元,如果在代码中实例化,一方面带有外观、位置等属性API代码操作更适合改成在组态中可视化拖拽配置、所见即所得;另一方面对数据模型图元的操作,非界面的比如图元之间层级逻辑关系、点击事件交互处理等,更适合代码来处理。
如果让图元对象在组态界面拖拽实例化,而不要通过代码new,这样界面相关的代码可以省掉直接拖拽编辑即可,同时也能在代码中访问图纸上的图标作为图元对象实例,通过API来做数据逻辑代码处理,这个结果就完美融合了代码逻辑和可视化配置两种方式各自的优势点!
现在具体讲实现方式:
4.1 组态界面拖放的图标类型都是ht.Data及其子类型
图纸上拖放的图元,基本都是ht.Node类型 + 图片image配置(对应API为setImage()),当前示例中ht.Grid就是从ht.Node派生的。图片配置就对应图标symbol,填充数据给ht.Node在数据模型中将界面展示到对应的View中。
4.2 数据模型ht.DataModel有getDataByTag()方法
该方法就是用来根据组态图纸中对图元可视化设置的tag属性,来获取实例化的对象!简言之,拖放一个图标到组态上,就是new了一个图元对象,通过tag就能在代码中获取到这个图元文件实例化的对象用于代码API操作!
4.3 本示例中更进一步,将Grid网格实例化放到组态上
首先要解决的问题就是ht.Grid类型如何能作为图标拖放到组态图纸上,因为目前拖放的绝大部分都是ht.Node类型,即时设置了tag,让代码获取到其对象实例,也没法代替代码中的new ht.Grid(),所以首先要解决组态工具条中扩展ht.Grid类型的内置组件图标
4.3.1 组态图标工具栏扩展内置指定类型的图标
如下图所示,要实现内置图标,并且是指定的ht.Grid类型,用于拖放一个或多个图标进来,结合不同的tag标签,实现在代码中需要多个new ht.Grid对象的地方,都可以通过dm.getDataByTag()用组态可视化拖拽生成的实例。
如下图所示,在client/config.js中,相应位置按照示例规则可以实现追加工具条中的内置图标组件。其中icon配置图标、type就是用来配置类型,这里就用我们需要的ht.Grid,然后iniData中可以配置初始化属性。
比如默认内置的image图片,可以默认为空,因为我们只需要ht.Grid类型对象给到代码,那么内容包括setImage()这个API的操作,都可以在代码中来设置这些属性了!
4.3.2 代码中根据标签tag获取到组态中拖放生成的实例对象
代码如下:
JavaScript |
运行效果
对比4.3.1的编辑状态,结合代码API调用和图纸拖拽编辑,运行效果如下:
注意,为了保障通过that.g2d().getView().appendChild(view)添加的左上角滑动条事件拖放正常,需要对应用图纸勾选可选中和事件处理,如下图所示:
5. * 拖放到组态的(派生类)图元,内置API属性如何开放到图纸配置
到了第4步我们知道可以添加ht.Node的派生类ht.Grid到工具栏,拖放到图纸中能实例化Grid对象根据getDataByTag获取到data数据图元对象后就能用其API了,那么如何这些API能在图纸上配置而不是一定要代码编写调用呢?
首先想到的是渲染元素方案,可以任意将对象的属性暴露出来给图纸配置,但是这里我们并不需要渲染元素提供dom或ht ui组件的实例呈现界面并return对象,只需要用图元对象本身调用api,动态用属性并暴露,其实很简单,渲染元素不一定都得要return和实例化,可以直接用data即可,截图及代码分别如下:
JavaScript |
可以看到,跟常规渲染元素模板差别很大,渲染元素可以是html dom对象,也可以是ht对象!渲染元素模板,以及设置渲染元素是否编辑状态随着图纸也矢量缩放;内置拖放矢量基本组件类型 ,完全可以只利用传入的data,也就是当前拖放到图纸上实例化的图元对象,直接调用API,用暴露的动态变量即可,无需实例化、以及return,也不需要用cache等其他传入参数!
此外,注意此渲染元素图标放到特定标记的目录分组,给config.js配置工具栏图标用的,用户直接拖放到图纸上,类型会是默认的ht.Node而并非ht.Grid,导致属性暴露后对应API调用传参不起作用甚至可能报错(可能存在派生类有但是基类没有的API接口):