页面树结构

版本比较

标识

  • 该行被添加。
  • 该行被删除。
  • 格式已经改变。

...

代码块
languagexml
collapsetrue
<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,
			}"
			style="
				font-size: 50px;
				display: flex;
				justify-content: center;
				align-items: center;
			"
			>{{ args.label }}</span
		>
		<span v-show="t_edit" ref="edit">
			<EditBox
				v-if="actEdit"
				:addinName="name"
				: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>
	</section>
	<section v-else :addinName="name">
		<span style="text-align: center">
			<div class="form-addin-icon">
				<!-- 控件拖放区图标的样式 -->
				<i class="iconfont"></i>
			</div>
			<!-- 在控件拖放区图标的名字 -->
			<div class="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",
		"basicArgs",
		"argsProps",
		"activeUUID",
		"store",
		"itemValue",
		"attributes",
		"relation",
		"editExtendInfo",
		"widgetAnnotation",
		"checkResult",
		"query_oprs",
		"route",
		"router",
		"root",
		"Message",
		"echarts",
	],

	components: {
		EditBox,
	},

	data() {
		return {
			//插件的名字
			name: name,
			//表示是否已经进入画布区
			t_preview: true,
			//是否需要编辑属性
			t_edit: false,
			// 属性配置项,按需设置
			addIcon: true,
			// 用于控制画布区的复制,删除和角标
			actEdit: false,
			actIndex: -1,
			setModal: false,
			// 支持的数据类型
			dataTypes: [],
			args: {
				// 用于提示用户名称
				title: "进阶控件",
				height: 300,
				heightType: "px",
				width: 100,
				widthType: "%",
				label: "Empty!",
				// 给出控件可以支持的事件类型
				eventRange: ["单击", "双击"],
				events: [],
			},
		};
	},
	created() {},
	// 生命周期函数,在dom元素生成之后调用
	mounted() {},
	computed: {
		// 需要用到实体类属性列表时使用
		filter_attributes() {
			return [];
		},
	},
	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;
		},
		// 返回控件绑定的目标属性,如果没有绑定返回undefined或者null
		getFormName() {
			return this.name;
		},
		getDataType(args) {
			return this.dataTypes;
		},
	},
};
</script>

<style>
</style>

应用端完整代码

在上述讨论之后,对应插件的应用端代码和入门控件的应用端类似,除了入门控件提到的setDisplayType, setArgs, getArgs以外,应用端代码还实现了用于和表单引擎交互的一些其他函数包括:

validate:当涉及到数据的时候表单引擎会调用这两个函数要求控件对自身的数据进行校验。

setError:当脚本在整个表单范围内发现存在错误的时候会调用setError请求控件显示错误信息,一般是将控件的外延设置为红色并给出提示。

setValue,getValue:表单引擎会将存储在数据库里的值通过这两个函数送给控件,由控件将取值显示出来或者读出控件正在绑定的取值。

getFormName:当控件绑定属性时,表单引擎会询问控件需要哪个属性的取值,收到这个值以后,表单引擎会调用setValue写入数值。

...

collapsetrue

...

装配指示文件

代码块
config:
  ignore:
  info:
    part-web:
      name: modeler
      cname: 建模端
      forms: # 表单控件
        BlankControl.vue:
          icon: "ios-apps-outline"
          cname: 进阶控件
          type: form/layout
      operations: # 操作插件
      mobileForms: # mobile表单控件
      mobileOperations: # mobile操作插件
      dependencies: # 外部依赖

应用端完整代码

在上述讨论之后,对应插件的应用端代码和入门控件的应用端类似,除了入门控件提到的setDisplayType, setArgs, getArgs以外,应用端代码还实现了用于和表单引擎交互的一些其他函数包括:

validate:当涉及到数据的时候表单引擎会调用这两个函数要求控件对自身的数据进行校验。

setError:当脚本在整个表单范围内发现存在错误的时候会调用setError请求控件显示错误信息,一般是将控件的外延设置为红色并给出提示。

setValue,getValue:表单引擎会将存储在数据库里的值通过这两个函数送给控件,由控件将取值显示出来或者读出控件正在绑定的取值。

getFormName:当控件绑定属性时,表单引擎会询问控件需要哪个属性的取值,收到这个值以后,表单引擎会调用setValue写入数值。

代码块
collapsetrue
<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: "BlankControl",
			// 属性配置项,按需设置
			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;
		},
		// 区域被双击以后的响应设置异常状态显示
		onDoubleClicksetError(error) {
			this.triggerEvent("双击")return this;
		},
		// 根据名字触发表单事件上配置的操作设置校验逻辑,返回true/false
		triggerEventvalidate(eventName) {
			let eventConfig = nullreturn true;
		},
		// 提取事件对应的操作参数返回对应的目标属性名称,引擎在渲染的时候将根据其返回值提取属性的取值调用setValue()
			if (this.args.events && this.args.events.length > 0getFormName() {
				eventConfig =return this.args.events.find((val) => {
					return val.name === eventName;
				})name;
		},
		// 获取插件对应的值,一般为this.value,特殊情况下需要进行格式转化,如日期字符串
		getValue() {
			return null;
			},
			// 触发实际操作
			if (eventConfig) {
				this.invokeOperation(
					eventConfig.opr_type,
					eventConfig.opr_path,
					this.itemValue,
					this.store
				)/*
          设置插件对应的值, 如果目标属性为空,则传入的items为空,主要是针对多对象加载控件时使用
          items目前为对应值,items将为目标对象列表
          特殊情况下需要进行格式转化再赋值
        */
		setValue(items) {
			return this;
		},
		// 现有表单加载在画布区加载控件的时候,会将之前的配置传入
		setArgs(args) {
			for (var i in args) {
				this.args[i] = args[i];
			}
			return this;
		},
	},
};
</script>

<style>
</style>

对于多对象控件,表单还会调用这些方法:

getSelected:返回当前空间中被用户选中的所有对象。

getAll:返回当前控件中显示出来的所有对象数组。

...

	// 表单保存的时候将控件的设置合并到表单自身的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>

对于多对象控件,表单还会调用这些方法:

  • getSelected:返回当前空间中被用户选中的所有对象。
  • getAll:返回当前控件中显示出来的所有对象数组。
  • freshData:根据给定的查询条件刷新表单,如果没有给定则使用默认的查询条件。

装配指示文件

代码块
languageyml
config:
  ignore:
  info:
    part-web:
      name: app
      cname: 应用端
      forms: # 表单控件
		...
        BlankControl.vue: form/layout
		...
      operations: # 操作插件
        ...
      dependencies: {}


3 小结

本章是在入门插件的基础上重点介绍了如何利用DWF提供的EditBox内部组件自动识别控件的属性,并自动产生属性编辑区对应输入界面的方法,使用EditBox的要点是:

...