...
为了支持用户可以设置事件和操作的绑定关系,需要增加两个属性
- 事件清单(eventRange):表示预置的时间类型,是一个数组。事件清单(eventRange):表示预置的事件类型,是一个数组。
- 事件列表(events):用于存储用户设置的事件和操作的绑定。
...
| 代码块 | ||
|---|---|---|
| ||
// Vue数据绑定的时候要求返回的结果
data() {
return {
// 插件的名字
name: "simpleCellGroup",
// 表示是否已经进入画布区
t_preview: falsetrue,
// 是否显示控件的属性编辑区
t_edit: false,
// 属性配置项,按需设置
args: {
// 前面已经描述,此处省略...
},
// 需要显示数据的集合,包括标题,图标,单元标题,单元内容,约定格式如下
cellData: {},
};
}, |
...
| 代码块 |
|---|
mounted() {
// 生命周期函数,实现数据加载
this.freshData();
},
methods: {
// 使用 `handleQueryData` 获取数据
...mapActions("DWF_form", ["handleQueryData"]),
// 此处省略若干函数的实现直接接入正题...
freshData() {
// 获取已经绑定的实体类、关联类类名,此类名会有一个后缀以便表明其类型,例如实体类:Asset&e,关联类:PartToPart&r
const bindTargetClass = this.args.bindTargetClass;
if (!bindTargetClass) {
console.error("no bindTargetClass");
return;
}
// 在使用的时候,需要将后缀抹去,利用正则表达式实现如下
const regexForTargetClass = /^([0-9a-zA-Z_]+)&([er])$/;
const glob = regexForTargetClass.exec(bindTargetClass);
if (glob === null) {
console.error(
`handleRefresh: invalid targetClass value -> ${bindTargetClass}`
);
return;
}
// 经过正则过滤后,得到干净的实体类经过正则过滤后,得到去除后缀的实体类/关联类的类名
let targetClass = glob[1];
let query = {
query: this.args.filterQuery,
pageSize: 4, //设计的时候可以根据需要设置翻页和大小
startIndex: 0,
};
this.handleQueryData({
targetClass: targetClass,
query: query,
fresh: true,
}).then((res) => {
const attributeForTitle = this.args.attributeForTitle;
const attributeForLabel = this.args.attributeForLabel;
let objs = res;
this.cellData = {
title: this.args.label,
icon: "ios-bookmarks-outline",
list: res,
};
});
},
},
}; |
...
| 代码块 | ||||||
|---|---|---|---|---|---|---|
| ||||||
<template>
<!--
建模时的预览前端,即插件的实际显示样式
:addinName="name"和ref="main"一般情况不可去除
-->
<section v-if="t_preview" :addinName="name" ref="main">
<!-- 在画布区的显示内容 -->
<span>
<!-- see https://www.iviewui.com/components/cell#JCYF -->
<Card :style="cardStyle" class="cell-group-wrapper">
<p slot="title">
<!-- change to slot syntax to avoid a bug, where :title may not respond to change as a prop. -->
<Icon :type="cellData.icon"></Icon>
{{ cellData.title }}
</p>
<CellGroup v-if="cellData.list && cellData.list.length">
<Cell
v-for="obj in cellData.list"
:key="obj.oid"
:title="String(obj[args.attributeForTitle])"
:label="String(obj[args.attributeForLabel])"
>
<Avatar :src="String(obj[args.attributeForIcon])" slot="icon" />
</Cell>
</CellGroup>
<div v-else class="no-result-prompt">无数据展示...</div>
</Card>
</span>
<span v-show="t_edit" ref="edit">
<!-- v-bind. see https://vuejs.org/v2/api/#v-bind -->
<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">
<!-- 从外部引用的辅助标签,用于显示属性 -->
<p>标题属性(Title)</p>
<AttributeSelector
:target-class="args.bindTargetClass"
v-model="args.attributeForTitle"
></AttributeSelector>
<p>详情属性(Label)</p>
<AttributeSelector
:target-class="args.bindTargetClass"
v-model="args.attributeForLabel"
></AttributeSelector>
<p>图标属性(Icon)</p>
<AttributeSelector
:target-class="args.bindTargetClass"
v-model="args.attributeForIcon"
></AttributeSelector>
<Button type="primary" long @click="freshData">刷新数据</Button>
</div>
</EditBox>
</span>
</section>
<section v-else :addinName="name">
<span style="text-align: center">
<div class="form-addin-icon">
<!-- 控件拖放区图标的样式
see: http://ise.thss.tsinghua.edu.cn/font_857540_a2fo0rqai0f/demo_index.html-->
<i class="iconfont"></i>
</div>
<!-- 在控件拖放区图标的名字 -->
<div class="form-addin-name">简单列表</div>
</span>
</section>
</template>
<script>
// 从本地引擎的一个自定义标签
import AttributeSelector from "./AttributeSelector";
import EditBox from "@/ext_components/form/_EditBox.vue";
import { mapGetters, mapActions } from "vuex";
export default {
props: [
"widgetAnnotationaddin",
"itemValuebasicArgs",
"attributesargsProps",
"routeactiveUUID",
"routerstore",
"rootitemValue",
"query_oprsattributes",
"relation",
"editExtendInfo",
"widgetAnnotation",
"checkResult",
"query_oprs",
"route",
"router",
"root",
"Message",
"echarts",
],
components: {
EditBox,
AttributeSelector,
},
// Vue数据绑定的时候要求返回的结果
data() {
return {
// 插件的名字
name: "simpleCellGroup",
// 表示是否已经进入画布区
t_preview: false,
// 是否显示控件的属性编辑区
t_edit: false,
// 属性配置项,按需设置
args: {
// 直接复用DWF默认的配置项,从而无需自行开发配置界面
bindTargetClass: "",
// 标签作为列表标题
label: "",
// 建模设置的过滤条件
filterQuery: "",
// 高度取值和单位
height: "",
heightType: "px",
// 宽度取值和单位
width: "",
widthType: "px",
// 背景色设置
back_color: "",
// 文字颜色设置
txt_fontColor: "",
/* ---------------------
* 下面是新增的自定义属性
* -------------------- */
// 单元格显示标题
attributeForTitle: "",
// 单元格显示内容
attributeForLabel: "",
// 显示图标对应属性
attributeForIcon: "",
// 在配置区支持的事件列表,元素为事件中文名
eventRange: ["单击"],
// 已被用户设置的事件列表,元素格式为 { opr_type: '', opr_path: '', name: '事件中文名' }
events: [],
},
cellData: {},
};
},
mounted() {
// 生命周期函数,实现数据加载
this.freshData();
},
computed: {
//...mapGetters("DWF_form", ["Entities", "Relations"]),
cardStyle() {
// 外层卡片的样式
const result = {};
if (this.args.height) {
result["height"] =
String(this.args.height) + (this.args.heightType || "px");
}
if (this.args.width) {
result["width"] =
String(this.args.width) + (this.args.widthType || "px");
}
if (this.args.back_color) {
result["backgroundColor"] = this.args.back_color;
}
if (this.args.txt_fontColor) {
result["color"] = this.args.txt_fontColor;
}
return result;
},
},
methods: {
// use `handleQueryData` to fetch data.
...mapActions("DWF_form", ["handleQueryData"]),
/*
在建模的时候传入,提示控件是在画布区还是在控件列表中
0:表示在画布区,已经被拖入
1:表示在控件区,准备被拖入
2: 表示在拖动中,还未放下
*/
setDisplayType(type) {
if (type == 0) this.t_preview =
true;
return this;
},
// 默认不用变化,返回编辑框供建模工具绘制,当控件拖入画布区以后被点击的时候触发
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表单保存的时候将控件的设置合并到表单自身的JSON中
getAllowgetArgs() {
return nullthis.args;
},
// 返回控件绑定的目标属性,如果没有绑定返回undefined或者null
getFormName() {
return null;
},
freshData() {
const bindTargetClass = this.args.bindTargetClass;
if (!bindTargetClass) {
console.error("no bindTargetClass");
return;
}
const regexForTargetClass = /^([0-9a-zA-Z_]+)&([er])$/;
const result = regexForTargetClass.exec(bindTargetClass);
if (result === null) {
console.error(
`handleRefresh: invalid targetClass value -> ${bindTargetClass}`
);
return;
}
let targetClass = result[1];
let query = {
query: this.args.filterQuery,
pageSize: 4,
startIndex: 0,
};
let objs = this.handleQueryData({
targetClass: targetClass,
query: query,
fresh: true,
}).then((res) => {
let objs = res;
this.cellData = {
title: this.args.label,
icon: "ios-bookmarks-outline",
list: res,
};
});
},
},
};
</script>
<style scoped>
/* 没有合适的数据的时候使用的样式 */
.no-result-prompt {
display: flex;
align-items: center;
justify-content: center;
background-color: #eeeeee;
color: #00000022;
font-weight: bold;
font-size: 2em;
}
/* hack to respond to height change.
see https://vue-loader.vuejs.org/guide/scoped-css.html#deep-selectors
*/
.cell-group-wrapper >>> .ivu-card-body {
position: relative;
height: calc(100% - 60px);
}
.cell-group-wrapper >>> .ivu-cell-group {
height: 100%;
overflow-y: auto;
}
</style> |
...
| 代码块 | ||||||
|---|---|---|---|---|---|---|
| ||||||
<template>
<!--
建模时的预览前端,即插件的实际显示样式
:addinName="name"和ref="main"一般情况不可去除
-->
<section :addinName="name" ref="main">
<!-- 在画布区的显示内容 -->
<span>
<!-- see https://www.iviewui.com/components/cell#JCYF -->
<Card :style="cardStyle" class="cell-group-wrapper">
<p slot="title">
<!-- change to slot syntax to avoid a bug, where :title may not respond to change as a prop. -->
<Icon :type="cellData.icon"></Icon>
{{ cellData.title }}
</p>
<CellGroup
v-if="cellData.list && cellData.list.length"
@on-click="onClick"
>
<Cell
v-for="(obj, idx) in cellData.list"
:key="obj.oid"
:name="idx"
:title="String(obj[args.attributeForTitle])"
:label="String(obj[args.attributeForLabel])"
@click="onClick"
>
<Avatar :src="String(obj[args.attributeForIcon])" slot="icon" />
</Cell>
</CellGroup>
<div v-else class="no-result-prompt">无数据展示...</div>
</Card>
</span>
</section>
</template>
<script>
// 引入内部图标备用
import "@/styles/component/iconfont.css";
import { mapActions } from "vuex";
export default {
props: [
"widgetAnnotation",
"itemValue",
"attributes",
"route",
"router",
"root",
"store",
"query_oprs",
],
// Vue数据绑定的时候要求返回的结果
data() {
return {
// 插件的名字
name: "simpleCellGroup",
// 表示是否已经进入画布区
t_preview: false,
// 是否显示控件的属性编辑区
t_edit: false,
// 属性配置项,按需设置
args: {
// 直接复用DWF默认的配置项,从而无需自行开发配置界面
bindTargetClass: "",
// 标签作为列表标题
label: "",
// 建模设置的过滤条件
filterQuery: "",
// 高度取值和单位
height: "",
heightType: "px",
// 宽度取值和单位
width: "",
widthType: "px",
// 背景色设置
back_color: "",
// 文字颜色设置
txt_fontColor: "",
/* ---------------------
* 下面是新增的自定义属性
* -------------------- */
// 单元格显示标题
attributeForTitle: "",
// 单元格显示内容
attributeForLabel: "",
// 已被用户设置的事件列表,元素格式为 { opr_type: '', opr_path: '', name: '事件中文名' }
events: [],
},
// 需要显示数据的集合,包括标题,图标,单元标题,单元内容,约定格式如下
cellData: {},
// 记录被点击选择的对象
cellSelected: {},
};
},
mounted() {
// 生命周期函数,实现数据加载
this.freshData();
},
computed: {
cardStyle() {
// 外层卡片的样式
const result = {};
if (this.args.height) {
result["height"] =
String(this.args.height) + (this.args.heightType || "px");
}
if (this.args.width) {
result["width"] =
String(this.args.width) + (this.args.widthType || "px");
}
if (this.args.back_color) {
result["backgroundColor"] = this.args.back_color;
}
if (this.args.txt_fontColor) {
result["color"] = this.args.txt_fontColor;
}
return result;
},
},
methods: {
// use `handleQueryData` to fetch data.
...mapActions("DWF_form", ["handleQueryData"]),
/*
在建模的时候传入,提示控件是在画布区还是在控件列表中
0:表示在画布区,已经被拖入
1:表示在控件区,准备被拖入
2: 表示在拖动中,还未放下
*/
setDisplayType(type) {
if (type == 0) this.t_preview = true;
return this;
},
// 默认不用变化,返回编辑框供建模工具绘制,当控件拖入画布区以后被点击的时候触发 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
getAllow() {
return null;
},
// 返回控件绑定的目标属性,如果没有绑定返回undefined或者null
getFormName() {
return null;
},
getSelected() {
return this.cellSelected;
},
getAll() {
return this.cellData.list;
},
// 单击事件
onClick(idx) {
this.cellSelected = this.cellData.list[idx];
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
);
}
},
// 刷新控件内部数据
freshData() {
const bindTargetClass = this.args.bindTargetClass;
if (!bindTargetClass) {
console.error("no bindTargetClass");
return;
}
const regexForTargetClass = /^([0-9a-zA-Z_]+)&([er])$/;
const glob = regexForTargetClass.exec(bindTargetClass);
if (glob === null) {
console.error(
`handleRefresh: invalid targetClass value -> ${bindTargetClass}`
);
return;
}
const targetClass = glob[1];
const query = this.args.filterQuery;
console.log(this.dwf_ctx);
this.handleQueryData({
targetClass: targetClass,
query: query,
fresh: true,
}).then((res) => {
const attributeForTitle = this.args.attributeForTitle;
const attributeForLabel = this.args.attributeForLabel;
let objs = res;
this.cellData = {
title: this.args.label,
icon: "ios-bookmarks-outline",
list: res,
};
});
},
},
};
</script>
<style scoped>
/* 没有合适的数据的时候使用的样式 */
.no-result-prompt {
display: flex;
align-items: center;
justify-content: center;
background-color: #eeeeee;
color: #00000022;
font-weight: bold;
font-size: 2em;
}
/* hack to respond to height change.
see https://vue-loader.vuejs.org/guide/scoped-css.html#deep-selectors
*/
.cell-group-wrapper >>> .ivu-card-body {
position: relative;
height: calc(100% - 60px);
}
.cell-group-wrapper >>> .ivu-cell-group {
height: 100%;
overflow-y: auto;
}
</style> |
...