...
- 已经使用了vue的数据绑定能力将整体宽度、整体高度和标签内容设置为args.height,heightType,width,widthType以及args.label五个参数。
- 其中<span v-show="t_edit" ref="edit">标签的内容仍然保持为空,因此如果此时调试控件是不会有和上述5个参数对应的属性编辑框出现的。
下面看如何得到属性编辑框。
2.2
...
给控件增加选项配置面板
为了给控件增加属性编辑功能,DWF提供了一个称之为EditBox的标签和配套的函数,只要控件的代码中包含args属性是DWF建模工具可以自动识别的,表单建模工具会自动为其在属性编辑区建立对应的输入控件。增加EditBox需要执行下面的步骤:为了给控件增加选项编辑功能,DWF提供了一个称之为EditBox的组件和配套的函数,只要控件的代码中包含args属性是DWF建模工具可以自动识别的,表单建模工具会自动为其在属性编辑区建立对应的输入控件。增加EditBox需要执行下面的步骤:
- 在控件vue文件中的<template>内增加<EditBox>标签并配置参数。
- 在脚本部分通过import引入_EditBox.vue文件和EditBox的component组件。
- 引入DWF表单引擎传入的prop参数,以便EditBox作为标签参数绑定。
...
首先,引入EditBox标签的方法很简单,如下代码所示:
| 代码块 | ||
|---|---|---|
| ||
<span v-show="t_edit" ref="edit"> <!--<EditBox v-if="actEdit" 属性编辑框区域 :addinName="name" 需要该插件获取attributes, router, route, root, query_oprs, itemValue的prop 对于不需要设置目标属性的插件,可以将attributes去掉 对于不需要设置事件的插件,可以将router, route, root, query_oprs去掉 --> <EditBox v-model="args :widgetAnnotation="widgetAnnotation" :editExtendInfo="editExtendInfo" ref="editbox" v-model="args" :attributes="filter_attributes" :router="router" :route="route" :root="root" :itemValue="itemValue" :query_oprs="query_oprs" :dataTypes="dataTypes" :targetclass="itemValue.data.targetClass" > <div slot="attribute">></div> <!-- <div slot="layout"></div> <div slot="operation"></div> </EditBox> </span> |
- 在EditBox里增加了一系列prop变量绑定,例如:attributes, router, route, root, query_oprs, itemValue。
- 在标签里如果出现需要自定义的部分可以分别在<div slot>标签里添加,这里先不考虑添加自定义属性。
<div slot="attribute">表示选项面板的基础选项。
<div slot="layout">表示涉及到布局和样式的面板。
<div slot="operation">表示事件的列表可以绑定操作。
引入EditBox脚本
接下来,直接引入EditBox标签对应的脚本实现,具体代码片段如下所示:
| 代码块 | ||
|---|---|---|
| ||
<script> // 引入控件自身的属性编辑框,DWF给出的标准实现 import EditBox from "@/ext_components/form/_EditBox.vue"; export default { // 引入控件的设置框对应的组件,对应在标签内可以引用 components: { EditBox, }, // 引入DWF的控件编辑辅助属性 props: [ 属性选项放置区域'addin', 'basicArgs', 'argsProps', 一般一个控件的prop都属于属性选项 --> </div> <div slot="layout"> <!-- 'activeUUID', 'store', 'itemValue', 'attributes', 样式选项放置区域 'relation', 'editExtendInfo', 仅有涉及到高度,宽度,对齐等样式的选项放在这里 --> </div> <div slot="operation"> <!-- 'widgetAnnotation', 'checkResult', 'query_oprs', 'route', 事件选项放置区域 --> </div> </EditBox> </span> |
- 在EditBox里增加了一系列prop变量绑定,例如:attributes, router, route, root, query_oprs, itemValue。
- 在标签里如果出现需要自定义的部分可以分别在<div slot>标签里添加,这里先不考虑添加自定义属性。
引入EditBox脚本
接下来,直接引入EditBox标签对应的脚本实现,具体代码片段如下所示:
| 代码块 | ||
|---|---|---|
| ||
<script> // 引入控件自身的属性编辑框,DWF给出的标准实现 import EditBox from "@/ext_components/form/_EditBox.vue"; export default { // 引入控件的设置框对应的组件,对应在标签内可以引用 components: { EditBox, }, // 引入DWF的控件编辑辅助属性 props: [ "widgetAnnotation", "itemValue", "attributes", "route", "router", "root", 'router', 'root', 'Message', 'echarts', ], ... </script> |
上述代码中import和component部分是标准操作直接引入即可
props是vue的对象传递机制,DWF在控件初始化的时候会将一些全局js变量传入,可以传入的对象并且被EditBox识别的有:上述代码中import和component部分是标准操作直接引入即可,props是vue的对象传递机制,DWF在控件初始化的时候会将一些全局js变量传入,可以传入的对象并且被EditBox识别的有:
- widgetAnnotation="widgetAnnotation":控件标注所用参数,DWF会通过props直接传递一个缺省值进来
- router="router":当前路由对象,DWF会通过props直接传递一个缺省值进来
- route="route":当前路由信息,DWF会通过props直接传递一个缺省值进来
- root="root":根组件对象,DWF会通过props直接传递一个缺省值进来
- itemValue="itemValue":表单对应JSON实例化以后的对象,DWF会通过props直接传递一个缺省值进来:表单对应JSON实例化以后的对象,DWF会通过props直接传递一个缺省值进来。
- dataTypes="dataTypes":目标属性类型:目标属性类型,需要返回一个数组表明可以接受的DWF数据类型。
- attributes="filter_attributes":过滤之后的目标属性:过滤之后的目标属性,需要控件里提供一个空的实现
- targetclass="itemValue.data.targetClass":表单类
...
- 通知表单建模工具需要保留在数据库中的参数。
- 还原表单上次保存的样子,此时控件的setArgs和getArgs会被建模工具调用。
- 在应用端表单展现的时候,展示真实的表单,同样的,控件的setArgs和getArgs会被建模工具调用。
- EditBox会自动扫描args的内容并自动识别可以产生属性配置的界面,这些属性在编辑以后,DWF会自动将其保存在表单对应JSON文件中,详细的自动识别清单可以参阅: DWF可自动识别的args参数
对于本章提到的args参数,height,heightType,width,widthType,label代码如下所示:
...
每一个控件需要一个title在args里面用于在建模阶段显示控件的名称,除此之外,对于本章例子里用到的args参数是:height,heightType,width,widthType,代码如下所示。
| 代码块 |
|---|
// Vue数据绑定的时候要求返回的结果 data() { return { //插件的名字 name: name, // Vue数据绑定的时候要求返回的结果 data() { return {表示是否已经进入画布区 t_preview: true, //是否需要编辑属性 t_edit: false, //插件的名字 属性配置项,按需设置 nameaddIcon: "blankControl"true, //表示是否已经进入画布区 用于控制画布区的复制,删除和角标 actEdit: false, actIndex: -1, t_previewsetModal: false, //是否需要编辑属性 支持的数据类型 t_editdataTypes: false[], args: { // 属性配置项,按需设置用于提示用户名称 argstitle: {"进阶控件", height: 300, heightType: "px", width: 100, widthType: "%": "%", label: "Empty!", // 给出控件可以支持的事件类型 eventRange: ["单击", "双击"], labelevents: "Empty!"[], }, }; }, |
2.3 为控件增加事件
除了配置项以外,控件内的事件也可以添加到里面来,如果需要添加控件自身的事件响应,具体操作是:
...
综上所述,如果希望为进阶的控件添加单击和双击事件,那么可以在args添加如下的代码:
| 代码块 | ||
|---|---|---|
| ||
| ||
// Vue数据绑定的时候要求返回的结果 data() { return { //插件的名字 name: name, //表示是否已经进入画布区 t_preview: true, // Vue数据绑定的时候要求返回的结果 data() { return {是否需要编辑属性 t_edit: false, // 属性配置项,按需设置 addIcon: true, //插件的名字 用于控制画布区的复制,删除和角标 nameactEdit: "blankControl"false, //表示是否已经进入画布区actIndex: -1, t_previewsetModal: false, //是否需要编辑属性// 支持的数据类型 dataTypes: [], t_editargs: false,{ // 属性配置项,按需设置用于提示用户名称 args title: {"进阶控件", height: 300, heightType: "px", width: 100, widthType: "%", label: "Empty!", // 给出控件可以支持的事件类型 eventRange: ["单击", "双击"], events: [], }, }; }, |
...
了解如何绑定原始事件并且触发操作以后,剩余的部分就非常简单了,在标签部分将标签的原始事件与函数对应起来,然后调用前面描述的triggerEvent方法触发事件配置对应的参数,先看如何绑定标签上的事件,以本章的进阶控件为例,原本设计了两个事件:单击和双击,运用vue规定的语法在template部分的标签中增加@click和@dbclick分别绑定到onClick() 和 onDoubleClick()方法上,代码如下:
| 代码块 | ||
|---|---|---|
| ||
| ||
<template> <!-- 建模时的预览前端,即插件的实际显示样式 :addinName="name"和ref="main"一般情况不可去除 --> <section :style="{ width: args.width + args.widthType, }" :addinName="name" ref="main"> <!-- 在画布区的显示内容 --> <span :style="{ height: args.height+ args.heightType, width: args.width + args.widthType, }" style=" font-size: 50px; display: flex; justify-content: center; align-items: center;" <!-- 绑定标签上的时间调用函数 --> @click="onClick" @dblclick="onDoubleClick" >{{args.label}}</span> </section> </template> |
...
| 代码块 | ||||
|---|---|---|---|---|
| ||||
<template>
<!--
建模时的预览前端,即插件的实际显示样式
:addinName="name"和ref="main"一般情况不可去除
-->
<section
v-if="t_preview"
:addinName="name"
ref="main"
:style="{
width: args.width + args.widthType,
}"
>
<!-- 在画布区的显示内容 -->
<span
:style="{
height: args.height + args.heightType,
width: 100
}" <span
:style="{
font-sizeheight: 50px;
display: flex;args.height + args.heightType,
justify-contentwidth: center;100,
align-items: center;"
>{{ args.label }}</span>
<span v-show="t_edit" ref="edit">}"
style="
<!--
font-size: 50px;
属性编辑框区域display: flex;
需要该插件获取attributes, router, route, root, query_oprs, itemValue的prop justify-content: center;
align-items: center;
对于不需要设置目标属性的插件,可以将attributes去掉"
对于不需要设置事件的插件,可以将router, route, root, query_oprs去掉>{{ args.label }}</span
>
-- <span v-show="t_edit" ref="edit">
<EditBox
v-modelif="argsactEdit"
:routeraddinName="routername"
:routewidgetAnnotation="routewidgetAnnotation"
:rooteditExtendInfo="rooteditExtendInfo"
:itemValueref="itemValueeditbox"
:query_oprsv-model="query_oprsargs"
:targetclassattributes="itemValue.data.targetClassfilter_attributes"
>:router="router"
<div slot:route="attributeroute">
<!--
属性选项放置区域
一般一个控件的prop都属于属性选项
-->
<:root="root"
:itemValue="itemValue"
:query_oprs="query_oprs"
:dataTypes="dataTypes"
:targetclass="itemValue.data.targetClass"
>
<div slot="attribute"></div>
<div slot="layout"></div>
<div slot="layoutoperation">></div>
</EditBox>
<!--
样式选项放置区域
仅有涉及到高度,宽度,对齐等样式的选项放在这里
-->
/span>
</section>
<section v-else :addinName="name">
<span style="text-align: center">
<div class="form-addin-icon">
<!-- 控件拖放区图标的样式 -->
<i class="iconfont"></i>
</div>
<!-- 在控件拖放区图标的名字 -->
<div slotclass="operation">form-addin-name">进阶控件</div>
</span>
<!--
</section>
</template>
<script>
import EditBox from "@/ext_components/form/_EditBox.vue";
const name = "BlankControl";
export default {
name: name,
事件选项放置区域
--> props: [
"addin",
</div>"basicArgs",
</EditBox>"argsProps",
</span>"activeUUID",
</section>
<section v-else :addinName="name">"store",
<span style="text-align: center;">"itemValue",
<div class="form-addin-icon">"attributes",
"relation",
<!-- 控件拖放区图标的样式 -->
<i class="iconfont"></i>
</div>
<!-- 在控件拖放区图标的名字 -->
<div class="form-addin-name">进阶控件</div>
</span>
</section>
</template>
<script>
// 引入控件自身的属性编辑框,DWF给出的标准实现
import EditBox from "@/ext_components/form/_EditBox.vue";
export default {
// 引入控件的设置框对应的组件,对应在标签内可以引用"editExtendInfo",
"widgetAnnotation",
"checkResult",
"query_oprs",
"route",
"router",
"root",
"Message",
"echarts",
],
components: {
EditBox,
},
//
引入DWF的控件编辑辅助属性
props: [data() {
"widgetAnnotation",return {
"itemValue",
"attributes" //插件的名字
name: name,
"route", //表示是否已经进入画布区
"router" t_preview: true,
"root", //是否需要编辑属性
"query_oprs" t_edit: false,
],
// Vue数据绑定的时候要求返回的结果
data() {属性配置项,按需设置
return { addIcon: true,
//插件的名字 用于控制画布区的复制,删除和角标
nameactEdit: "blankControl"false,
//表示是否已经进入画布区actIndex: -1,
t_previewsetModal: false,
//是否需要编辑属性 支持的数据类型
t_editdataTypes: false,
[],
args: {
// 属性配置项,按需设置用于提示用户名称
argstitle: {"进阶控件",
height: 300,
heightType: "px",
width: 100,
widthType: "%",
label: "Empty!",
// 给出控件可以支持的事件类型
eventRange: ["单击", "双击"],
events: [],
},
};
},
methods:created() {},
//* 在建模的时候传入,提示控件是在画布区还是在控件列表中生命周期函数,在dom元素生成之后调用
0:表示在画布区,已经被拖入
1:表示在控件区,准备被拖入
2: 表示在拖动中,还未放下mounted() {},
computed: {
*// 需要用到实体类属性列表时使用
setDisplayTypefilter_attributes(type) {
if (type == 0) this.t_preview = truereturn [];
return this;},
},
methods: {
// 默认不用变化,返回编辑框供建模工具绘制,当控件拖入画布区以后被点击的时候触发
getEditBox() {
this.t_edit = true;
return this.$refs.edit;
},
// 当插件无法直接通过style设置高度时,使用setHeight方法设置高度
setHeight() {
if (!this.$refs.main) return;
},
// 现有表单加载在画布区加载控件的时候,会将之前的配置传入
setArgs(args) {
for (var i in args) {
this.args[i] = args[i];
}
return this;
},
// 表单保存的时候将控件的设置合并到表单自身的JSON中
getArgs() {
return this.args;
},
// 是否允许其他子控件拖入,如果不允许则返回null返回控件绑定的目标属性,如果没有绑定返回undefined或者null
getAllowgetFormName() {
return nullthis.name;
},
// 返回控件绑定的目标属性,如果没有绑定返回undefined或者null
getFormName(getDataType(args) {
return nullthis.dataTypes;
},
},
};
</script>
<style>
</style> |
...
| 代码块 | ||
|---|---|---|
| ||
<template>
<!--
建模时的预览前端,即插件的实际显示样式
:addinName="name"和ref="main"一般情况不可去除
-->
<section :style="{
width: args.width + args.widthType,
}" :addinName="name" ref="main">
<!-- 在画布区的显示内容 -->
<span
:style="{
height: args.height+ args.heightType,
width: args.width + args.widthType,
}"
style="
font-size: 50px;
display: flex;
justify-content: center;
align-items: center;"
@click="onClick"
@dblclick="onDoubleClick"
>{{args.label}}</span>
</section>
</template>
<script>
export default {
props: ["itemValue", "store"],
// Vue数据绑定的时候要求返回的结果
data() {
return {
//插件的名字
name: "blankControlBlankControl",
// 属性配置项,按需设置
args: {
// 用于提示用户名称
title: "进阶控件",
height: 300,
heightType: "px",
width: 100,
widthType: "%",
label: "Empty!"!",
// 给出控件可以支持的事件类型
eventRange: ["单击", "双击"],
events: [],
},
};
},
methods: {
/*
type取值范围为 create, visit, edit
需要根据三个状态修改具体前端和逻辑
一般情况下:
create创建态: 无数据,可编辑
visit浏览态: 有数据,不可编辑
edit编辑态: 有数据,可编辑
*/
setDisplayType(type) {
return this;
},
// 设置异常状态显示
setError(error) {
return this;
},
// 设置校验逻辑,返回true/false
validate() {
return true;
},
// 返回对应的目标属性名称,引擎在渲染的时候将根据其返回值提取属性的取值调用setValue()
getFormName() {
return nullthis.name;
},
// 获取插件对应的值,一般为this.value,特殊情况下需要进行格式转化,如日期字符串
getValue() {
return null;
},
/*
设置插件对应的值, 如果目标属性为空,则传入的items为空,主要是针对多对象加载控件时使用
items目前为对应值,items将为目标对象列表
特殊情况下需要进行格式转化再赋值
*/
setValue(items) {
return this;
},
// 现有表单加载在画布区加载控件的时候,会将之前的配置传入
setArgs(args) {
for (var i in args) {
this.args[i] = args[i];
}
return this;
},
// 表单保存的时候将控件的设置合并到表单自身的JSON中
getArgs() {
return this.args;
},
// 区域被单击以后的响应
onClick() {
this.triggerEvent("单击");
},
// 区域被双击以后的响应
onDoubleClick() {
this.triggerEvent("双击");
},
// 根据名字触发表单事件上配置的操作
triggerEvent(eventName) {
let eventConfig = null;
// 提取事件对应的操作参数
if (this.args.events && this.args.events.length > 0) {
eventConfig = this.args.events.find((val) => {
return val.name === eventName;
});
}
// 触发实际操作
if (eventConfig) {
this.invokeOperation(
eventConfig.opr_type,
eventConfig.opr_path,
this.itemValue,
this.store
);
}
},
},
};
</script>
<style>
</style> |
...
本章在最后还介绍了控件应用端的一些额外函数,当控件需要和DWF数据绑定并进行交互的时候这些函数就会被调用,接下来在表单建模进阶里将会介绍控件如何与后台数据交互。
4 附件
建模端进阶控件:
| View file | ||||
|---|---|---|---|---|
|
| View file | ||||
|---|---|---|---|---|
|
应用端进阶控件:
| View file | ||||
|---|---|---|---|---|
|