如何记录验证element后台管理系统中表单(表格?)的修改痕迹
如何记录验证element后台管理系统中表单(表格?)的修改痕迹
大家好我是极速网吧的黒网吧天才少年,主要打1号位,这篇文章记录一下工作中遇到的一个比较有意思的需求,防止下次开发的时候忘记,同时希望大佬们给点建议
最近接了个需求,要求我写一个表格,这个表格用户可以自由增加删除行以及修改行内的数据,输入的内容有一定的验证要求,同时记录下用户的操作,在上传数据的时候提示用户进行了哪些操作。如图:
后端返回以及要求数据结构:
const tableList = [{ section_name: "老八", section_id:1 grade_list: ["臭豆腐", "俘虏", "臭撸虾", "嘎嘣脆嗲", "胡罗贝", "柠檬"] }] 复制代码
这是表格中的内容,为数组对象,其中我们要记录修改痕迹的grade_list是不带id标识的,最终要求返回的数据也跟这个一致。
分析思路
记录修改痕迹,我们只需要在进入弹窗的时候记录一份原始数据,然后再比对原始数据以及提交时候的数据即可。
this.myTable = row.grade_list.map((key,index) => ({ id:index, section_name:row.section_name, grade_name:key })) this.originTable = JSON.parse(JSON.stringify(this.myTable)) 复制代码
第一步:验证重复
当有重复项的时候直接阻止进入下一步,同时在表格中弹窗提示重复,样式怎么写呢?直接去element源码把el-form的验证样式复制过来即可
<!-- html内容 --> <el-table border :data="myTable" > <el-table-column type="index" label="序号"></el-table-column> <el-table-column prop="section_name" label="姓名"></el-table-column> <el-table-column label="最爱的食物"> <template slot-scope="{ row,$index }"> <div class="el-form-item" :class="{ 'is-error': errorObj.hasOwnProperty($index) }"> <div class="el-form-item__content"> <el-input v-model="row.grade_name" maxlength="10"></el-input> <transition name="el-zoom-in-top"> <div v-if="errorObj.hasOwnProperty($index)" class="el-form-item__error" > {{errorObj[$index]}} </div> </transition> </div> </div> </template> </el-table-column> <el-table-column label="操作"> <template slot-scope="{ row,$index }"> <el-button @click="delClass(row,$index)">删除</el-button> </template> </el-table-column> </el-table> <!-- js内容 --> <script> 需要的data: data(){ return{ myTable:[], originTable:[], tempRow:{}, //验证类 validateState:'error', errorObj:{}, } } 绑定在保存按钮点击事件上的方法: putGrades(){ ... //去空 this.myTable = this.myTable.filter(key=> key.grade_name.trim() !== '') // 验证重复,new一个名字为键序号数组为值的map,序号的length大于1的时候说明有重复 let map = new Map() this.errorObj = {} this.myTable.forEach((key,index)=>{ //遇到重复的名字,重新把名字对应的序号 if(map.has(key.grade_name)){ let oldVal = map.get(key.grade_name) map.set(key.grade_name,[...oldVal,index]) return } map.set(key.grade_name,[index]) }) map.forEach((value)=>{ if(value.length > 1){ value.forEach(key=> { //存入重复项以及验证错误的原因 this.$set(this.errorObj,key,'老八不喜欢重复的食物!') }) } }) //有重复阻止发送请求 if(Object.keys(this.errorObj).length !== 0) return ... } </script> 复制代码
因为错误信息errorObj因为不确定有多少项,所以没法在data中直接写上让vue动态绑定,所以在方法中用了vue.set
的方法手动来动态绑定,通过数组中的index来保证与原数组一一对应的关系。通过这个思路,我可以通过写其他的方法来验证其他不同的规则,比如是否含有字母、手机号规则等,只需要遍历数组一次,将不符合规则的index以及错误信息存入errorObj即可。
第二步:记录修改痕迹
记录修改痕迹,需要先区别新增项与原始数组中的项,我在原始数组的每一项中都添加一个id,id的值跟index一致,新增项中则没有id。这样就能将新增与原有区分开来,如此只需两步就可以记录下修改痕迹了。
ps:“新”代表要提交的数组,“旧”代表我们拷贝的那份数组
1:判断新旧是否有重名,有重名的先直接去掉,属于不变的组
2.1:判断新旧中有id的名字是否一致,不一致的部分去掉,属于修改组
2.2:判断新旧带id的数量是否一致,新中少了的部分去掉,为删除组,剩下的都是新增组
... //第1步,判断新旧是否有重名,有重名的先直接去掉,属于不变的组 let originMap = new Map() this.originTable.forEach(key =>{ originMap.set(key.grade_name,key.id) }) let tempNew = this.myTable.filter((key) => { if(originMap.has(key.grade_name)) { originMap.delete(key.grade_name) return false } return true }) //如果全部重名即没有修改,直接返回 if(tempNew.length === 0) return //第2.1步,判断有id的名字是否一致,不一致属于修改组 //第2.2步,判断新旧带id的数量是否一致,origin少了的部分为删除组 //第3步,剩下的都是新增组 //反转originMap中键值对 let idMap = new Map() originMap.forEach((value,key)=>{ idMap.set(value,key) }) let edited = new Map() let noIDGrade = [] tempNew.forEach(key=>{ if(key.id !== undefined) { edited.set(idMap.get(key.id),key.grade_name) idMap.delete(key.id) }else{ noIDGrade.push(key.grade_name) } }) const h = this.$createElement; let renderEdit = [] let renderAdd = [] let renderDel = [] edited.forEach((value,key)=>{ renderEdit.push(h('p',`${key}修改为${value}`)) }) noIDGrade.forEach((value)=>{ renderDel.push(h('p',`新增:${value}`)) }) idMap.forEach((value)=>{ renderAdd.push(h('p',`已删除:${value}`)) }) //判断修改组、新增组、删除组是否为空,为空的话阻止上传 if(renderEdit.length === 0 && renderAdd.length === 0 && renderDel.length === 0) return this.$msgbox({ title: "修改确认", message: h("div", null, [ h( "p",renderEdit ), h( "p",renderAdd ), h( "p",renderDel ), ]), showCancelButton: true, showClose: false, confirmButtonText: "确认", cancelButtonText: "取消" }) ... 复制代码
因为修改组必须以键值对的形式出现,即xxx修改为xxx,所以修改组我用map记录,删除组跟新增组都直接存名字的值。最后效果:
总结&求助
感觉自己写的这个东西很垃圾,遍历了很多次,用了许多额外的空间,创造了一堆数组跟map,特别是反转map键值对显得特别蠢,有没有其他思路或者写法上可以更简洁,恳请大神们给个提示,在掘金搜了一下没看到有写校验表单的相关内容。
完整的项目地址:github.com/Eating-Eati…
- 【DWZ】表单验证规则介绍,与如何修改表单验证,如何添加自定义表单验证
- bootstrap表单验证插件 经验记录 与RSA加密事件配合修改
- jQuery表单验证和添加表格 删除修改
- bootstrap表单验证插件 经验记录 与RSA加密事件配合修改
- ExtJs 备忘录(7)—— GirdPanl表格(三) [ 统计|查看、修改单行记录 ]
- 如何对Exchange SMTP身份验证记录进行分析
- HTML表单如何利用JavaScript自动验证其格式
- 用flex如何制作不规则的表格,进行打印预览。而且可以打印。譬如制作如下表单:
- 如何对Exchange SMTP身份验证记录进行分析
- MySQL如何修改表格的字符集,如何修改某个字段的字符集
- 关于表格动态添加行并处理相关表单元素的一些修改----优化for重用(3) --最终版
- [学习][记录][转]JS组件系列——Form表单验证神器: BootstrapValidator
- 备战秋招——记录自己学习的第七天(Django项目难点拆分——利用modelform实现用户验证、修改用户信息)
- AngularJS学习记录-表单验证
- 如何验证下载的linux内核是否被修改过
- 大表格,多Form元素的提交 判断表单数据是否有被修改过
- 如何在Asp.Net页面中使用javascript进行表单验证?
- 如何对系统中设置的修改记录增加log日志
- 关于bootstrap验证表单如何ajax提交