自定义表单开发指导

流程自定义表单是使用 Vue js 和原生 HTML 来实现,并以 组件混入 的形式支持 在线表单 js 扩展
我们还封装了很多前端控件指令,目前涵盖了常见的表单控件类型

自定义表单架构

VUE 版本自定义表单 js扩展

混入形式植入扩展 js,data , 适用于 PC端 与 移动端 在线表单


<script>
<!--脚本将会混入表单自定义表单控件-->
window.custFormComponentMixin ={
data: function () {
return {
"hello":"helloWorld"
};
},
created:function(){
console.log("初始化执行");
},
methods:{
custValid:function(){
// 表单支持的扩展业务校验方法
if(!this.hello){
$.Dialog.warn("请录入 hello 信息!");
return false;
}
return true;
},
test:function(){
console.info("aaaaaaaaaaaaaaaaaaaaaaaaaa")
$.Dialog.success(this.hello);
}
}
}
</script>

如图

自定义表单 组件扩展、公共方法扩展可以参考 bpm-explorer\assets\vue\service\form\formService.js
公共组件目录 bpm-explorer\assets\vue\components\form\

Angular 自定义表单js扩展

javascript引入

  • 直接在百度编辑器中编辑HTML直接加入 <script> 脚本
  • 使用url相对路径引入
<script type="text/javascript" src="/js/aaa/bbb.js"></script>

javascript脚本方式

  • 使用子controller来实现【推荐】
    在某段DOM元素上添加 ng-controller="testCtrl"
    在该DOM元素内部、可以使用ng-click 来触发 controllerscope上面定义的function
    controller会存在单独作用域,在该作用域中可以自由扩展业务逻辑。
<script type="text/javascript">
var testCtrl = [ '$scope', 'baseService', 'xxxService', function(scope, baseService, xxxService) {
// scope.fn = function(){}...
}
)]

</script>
  • 传统形式的js扩展方法,适用第一次适用angular的朋友
    使用传统的方式获取到$scope 或者service 然后像 scope 中注入function,或者做一些操作
    如下面脚本,在页面加载时向scope中加入 test方法,那么我们便可以在页面中使用 ng-click="test()"来触发该方法执行
$(function(){
var scope = ngUtil.getScope();
scope.test = function(){
///
}
var service = ngUtil.getService("serviceName");
var data = scope.data;
scope.$apply(function(){
//消化改变
})
})

请注意自己处理$digest的动作

公共服务方法注入

  1. custForm.js 中引入xxx模块js。
  2. formServiceModule 添加该公共模块xxxModel。
  3. 在controller中注入xxx模块中的的service。
    如此便可以在controller中使用该service功能了
    虽然做法略有侵入,但是并没有太大影响,angular依赖注入对模块化支持很好。我们不必在意对表单公共服务的入侵

表单业务校验扩展

除了内置的表单校验外,我们支持自定义的表单校验
在业务表单,或者流程表单中,提交数据之前都会尝试执行 scope.custValid 方法(vue 版本则会尝试调用混入组件的 custValid )
当使用子类controller的形式,需要将custValid 注册入scope.$parent
return false的时候,提交表单将被终止

socpe.custValid = function(){
if(!scope.data.user.name){
$.Dialog.error("用户姓名不能为空");
return false;
}
return true;
}

表单业务数据格式

假设 一个老师Teacher 带多个班级Class,每个班级存在多个学生, 班级与老师其实是多对多关系, 我们在老师和班级中添加一条 关系表ClassRel
一个ClassRel 对应一个班级,一个班级对应多个学生Student
业务对象数据结构如下:

Teacher:{
id:id,
name:name,
ClassRelList:[{ // teacher与之一对多
id:id,
relType:"临时\代课\正式",
Class{ // ClassRel与之一对一
id:xxx,
name:xxx,
....
studentList[ // Class与之 一对多
{},{}...
]
}
}]
}

表单指令

详细介绍请参考 表单插件

表单函数计算

用于子表字段 合计统计,平均值计算,数字字段 加减乘除运算 (vue版本提供)

表单日期计算

常用于 开始日期 结束日期 天数/小时/月数 的表单计算,并讲计算结果赋值给某个字段 (vue版本提供)

日期比较校验

常用于 开始日期 结束日期 之间的日期 校验,比如结束日期 必须大于 开始日期 (vue版本提供)

表单维护与日志

业务系统的表单数据是存储于数据库中form_def表 中

表单支持 Git 备份
需要在配置文件中配置 表单备份的目录,建议使用项目代码 资源目录
当代码提交时候、讲本地表单提交到 Git 服务器

formDefBackupPath = D:\\git\\agile-bpm-pom\\bpm\\form\\form-core\\src\\main\\resources\\form

每次表单保存后,系统会会以分类作为目录,formKey 为文件名,保存表单到该目录
当然该文件不会对表单数据有任何影响,仅仅是为了git文件日志备份,查看更新情况

后记

最初我们希望表单做在前端项目中,让表单内容前后端分离,并有所缓存,后端只维护表单的存在,编辑器依然可以以流的形式读取内容并维护
但是它丧失了紧急情况下在线修改表单的灵活性。而且会让场景变得复杂。最终还是使用数据库存储表单(比如在生产在线修改了表单,多机器部署时,修改内容合并等场景)