...
为了支持用户可以设置事件和操作的绑定关系,需要增加两个属性
- 事件清单(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> |
...