本篇内容可能会偏长,从我的视角看三重绑定和代码批量创建是高度绑定,三重绑定目的就是让代码批量创建更加的自动一点,虽然说理论上这个和你用udt批量生成view视图可能没有什么本质上的差距,以及当我遇到了很多问题才将三重绑定完成后才意识到,或许也可以用到其他地方。但是已经没东西给我做了,记录一下吧。
利用代码创建tag,其实网上有相似的教程我也差不多是照搬,但是并没有后续的东西了。既然都已经通过代码自动创建出了一堆嵌入式view视图了,传参为什么还要我手动绑,太麻烦了,这是我当时批量生成后的想法。那要完成生成的视图自动和参数对应上应该怎么处理呢?和之前udt绑view应该有相似之处,那么应该也是在view视图的绑定上做动作,思路也确实没错,当时的老工程师给我的办法是利用ignition的绑定功能脚本化(我还不足够了解这些功能,所以去问了),实现view视图批量生成后仍然可以对应的上相应的tag,这样对应上了tag和view视图之间的数据流,但是,没有这么简单,因为ignition似乎也存在作用域的问题,即在某些脚本页面似乎无法访问tag路径或者是无法访问view视图参数,具体哪些页面时间太久我已经忘了,只能提一嘴。
代码批量创建tag
批量创建tag之前需要先创建一个udt实例,理论上来说直接创建tag应该也可以批量创建tag,有udt模版更加的规范与方便,如果后期需要修改tag结构也可以通过udt批量修改实现,创建完udt实例即tag后,选择copy json选项复制tag的相应格式,截图操作如下图所示:
复制好相应的格式后,代码在脚本编辑器中编写,代码如下:
tagtest是复制copy json的结果,然后利用python深拷贝,即批量创建不同的tagtest值,存入taglist数组中,利用 system.tag.configure 执行代码,configure函数中,第一个参数是对应的文件夹的路径,或者说是批量创建的tag需要被放在哪里,可以通过copy path获得,第二个参数是需要被批量创建的tag的json格式,第三个参数是冲突配置策略,o代表冲突时覆盖原有配置。创建完成后,id这个参数应该是有问题的,我们还需要其他的代码来修改他,当然显然的代码可以组合到一起,但是我当时似乎没有留下记录,代码如下所示:
现在批量创建的tag应该是没有其他的问题了,如果还需要增加其他字段也可以直接在代码上进行修改添加即可。 显然的在代码中tag的相关属性是作为json字段存在的,照抄就行了,不赘述。
代码批量创建视图
首先,因为批量创建的相关内容是我试用期的时候写的,当时整体内容虽然已经构思的差不多了,但是没等到我逐渐实现就已经结束试用期了,所以对于该部分的内容记载不足够完善,只能是出于记录的目的继续完善这篇博客了,若有不足和不通顺之处还望多包涵。
批量创建视图需要利用flex repeater功能,即嵌入式视图的操作,毕竟我们需要将视图作为一个可以通过代码复制的元素来生成,接下来是批量创建视图,理论是没错的,不过就是写代码的地方可以更换位置,所需操作如下所示,并附上代码:
def transform(self, value, quality, timestamp):
from copy import deepcopy
demo={
"instanceStyle": {
"classes": ""
},
"instancePosition": {},
"carcode": u"",
"cardescript": u"",
"select": {
"boolean": False,
"num": u"{}"
},
"serialid": u"V{}"
}
idarray=\['A','B','C','D','E','F','G','H','I','J']
result = \[]
for i in range(0,30):
temp=deepcopy(demo)
temp\['select']\['num']=temp\['select']\['num'].format(i+1)
temp\['serialid']=temp\['serialid'].format(str(i+1).zfill(2)+idarray\[int(i/3)])
result.append(temp)
return result
可以看出主要是利用transform函数,这里也是类似于照抄之前的批量创建tag的代码,因为此处嵌入式视图的相关元素内容仍然可以被复制,如下图所示:
显然的,我代码中的demo部分就是嵌入式视图的相关属性,此处我还做了其他的多余操作是因为考虑到后续可能的搜索功能以及实现这个需求时所说的一版数据的要求,给每个可能存储数据的数据块加上一个单独的特殊的编号方便后期的索引和分辨,我的数据分类规则也是显然的比较简单的就不多做解释了。此处当时设想时,其实还想过利用类似于雪花编号之类的进行实现,但是学习了有关雪花编号的内容后,觉得编号太长了,适合放到数据库中作为唯一索引而不是用于展示在页面上,无奈只能自己构思。
三重绑定
完成了上述所有内容后,有一个显然的问题出来了,数据并不互通,要么我们进行手动绑定,要么开始琢磨有关自动绑定的办法,或者说是,将数据从tag,到view视图和主页面嵌入式视图之间相互传递的功能需要怎么实现。那么实现的内容其实仍然有可以参考的部分,在之前实现view批量绑定tag就有可以参考的部分,因为tag是被批量创建的,view可以直接和udt模版绑定然后和实例绑定,当然,这是因为view给出了这个功能,但同样的也可以作为一个参考。现在我们的udt和tag都是代码批量生成的,那么对于代码中的内容来说,初始的tag和view视图的参数,那么也可以作为一个模版来进行绑定,我们只需要生成时,根据当前view视图会自增的id序号,即1-30来区分即可,这也是ignition支持的功能之一。
批量视图和批量tag即udt之间的数据传输
在之前的博客中提到过,我们可以利用view批量绑定tag,绑定之后只要拖动tag到待编辑的页面上即可生成新的根据tag相关数据展示的view视图,但是,当我们尝试利用flex repeater批量生成view视图时,绑定关系失效,原因在后面讲解,那么我思考还能实现这一设想的功能就是value change事件,是的,三重绑定听上去很高大上,但是内核就是足够的value change事件,在三重绑定的每个数据上添加一个value change事件,如果是视图上的相关元素可能需要修改成相关的change脚本,当tag,批量view视图和嵌入式视图中三者有一个的数据被修改时,触发change脚本,同步修改另外两个的数据。
因为除了展示出来的嵌入式视图是会被用户修改的,其他的只有我们从程序的角度去修改,所以也不用担心数据冲突的问题,我们此处的tag是作为一个储存数据的中转来实现作用的,即虚点。同时,因为我们的tag,视图的序号都是规律的,所以我们只要知道当前tag或者视图的一个编号即可同步修改其他数据,因为批量生成的缘故,所有tag和嵌入式视图的路径都是固定的,我觉得这点不难理解,所以change事件无法获取其他数据地址的问题很简单的即可解决。可能会觉得说,只要修改嵌入式视图的数据和tag就可以了,模版view视图不需要修改,这个是ignition的特性决定的,因为存在有些页面访问不了tag,有些页面访问不了嵌入式view视图,可以自行尝试。接下来是实现绑定的change事件脚本,截图如下所示:
此处注意是在text右侧右击鼠标添加valuechange事件,代码的话,我认为是比较简单的,就是简单的拼凑字符串,就不赘述了,整个valuechanged事件的作用就是,当text文本框的值改变时,将变化的值传递到对应的params参数上,同时写入对应的tag上。
批量视图和嵌入式视图之间的数据传输
下面给出tag的自动绑定,利用绑定功能的脚本化语言,也是官网的一个功能之一,截图如下所示:
首先修改props中的绑定,要点击text属性旁边的链接样式图标,在tag页中选择间接绑定,即indirect,先在tagpath中输入一个预定的tag路径,然后设置其中需要变化的量变为{},并添加变量名,添加变量名后,下面会自动弹出id这个变量的参数,设置其属性,即预想的需要赋给变化的id的值,此处需要选择视图属性里面的num属性,即整个模版视图中,自己添加的num参数,因为最后,此num参数是通过代码脚本进行赋值的,这个num就是自增的变量,同时,需要在下面的设置中,设置属性为双向写入,即Bidirectional需要勾选,这个选项代表数据写回。注意,属性里面需要设置一个tostring的类型转换,因为此处需要的数据显然的是字符串类型,而num虽然是复选框中的序号文本,但是稳妥起见增加一个转换的步骤,因为默认输入序号的时候会提示报错,给了一个整型,但预期是字符型。那么到目前为止,text的绑定关系已经修改为绑定到tag上了,只要修改tag,那么text文本也会自动修改。现在我们完成了tag和text也就是模版view的数据绑定。
那么还剩下嵌入式view视图的数据不知道怎么操作,而根据之前的博客内容可以知道,我们可以通过模版view视图的params参数和嵌入式视图之间进行数据通信。因为模版视图的参数本身也是可以添加脚本的,所以下一步就是在模版视图的param参数中添加value change脚本,每当param参数值改变时,将值写入到tag中,因为tag和text的绑定关系,会自动写入到text中。脚本如图所示:
对于text序号期望类型不一致的解决方法,添加一个转换脚本或者类似的利用表达式的tostring应该也是一样的,代码如下图所示: