作者:艾志谋 Zhimou.Ai
时间:2017-09-09
版本:1.0
问题描述
在Hap前台页面的开发中,经常会使用到头行结构,一个头表对应一个或者多个行表,类似于如下结构:

这种头行结构页面的头表和行表的新增、修改、保存操作一般都是分开的,因为他们本身对应的是数据库中的多张表,尤其是行表,可能有多个Tab页,那么就会对应更多的表。
在这样的页面中如果在行表的不同Tab页中都新增或者修改了信息,原始的操作是应该没操作一个Tab页就点击一下这恶Tab页上的保存按钮,但是如果用户忘记了点击Tab页上的保存,而直接操作另外的Tab页,最后也都忘记了保存,只点击了一下头表中的保存按钮就关闭了页面;或者用户想一次添加多个Tab页的信息,最后只点击一次啊头表的保存按钮,那么就会造成数据丢失的情况。
所以在头表的保存按钮上添加统一保存行表Tab页数据的功能,可以最大限度的防止用户误操作而导致数据丢失的情况发生
基本思路
基本实现思路是直接在头表的保存按钮的方法里面调用行表viewModel中的saveChanges()方法。但是直接调用会出现bug,需要对原有的saveChanges()方法进行一些调整。
操作方法
1、首先重写框架自带的viewModel中的saveChanges()方法
Hap封装好的saveChanges()方法执行后会无论成功失败都有一个json格式的返回值,如果成功,则返回值中会有success:false,反之则是success:false。
成功:
{rows: [{__status: "update", _token: "206c0679957ddb7b90dc0aa905514895"…}],…}
rows:[{__status: "update", _token: "206c0679957ddb7b90dc0aa905514895"…}]
success:true
total:1
失败:
{message: "资质类型为:1106需要更新修改原因!", success: false}
message:"资质类型为:1106需要更新修改原因!"
success:false
而如果grid中没有任何数据改变就执行saveChanges()方法则不会有返回值,此时直接使用resp.response就会报错,因此需要判断一下json是否为空。
所以最基本的重写如下:
saveFn:function () {
quaInfoGrid.saveChanges().done(function (json) {
if (json != null){
if (json.response.success){
//这里写保存执行成之后的操作
}
}
}
}
但是此时,行表grid中的数据还会有一些校验,例如非空、内容限制之类,如果校验没有通过直接调用saveChanges()方法也会出错,此时.done()方法会报错,因为saveChanges()方法并未成功执行,因此还需要对grid中变化的数据做一个校验:
首先对该grid开启数据校验:
$('#quaInfoGrid').kendoValidator({});
然后在调用方法之前首先确认数据校验成功,再执行saveChanges()方法,因此saveChanges()方法修改如下:
saveFn:function () {
var validatorQuaInfo = $("#quaInfoGrid").data("kendoValidator")
if (validatorQuaInfo.validate()) {
quaInfoGrid.saveChanges().done(function (json) {
if (json != null){
if (json.response.success){
//这里写保存执行成之后的操作
}
}
})
}
}
2、对头表和行表的数据保存操作做统一校验
如果有一个grid没有爆粗成功则整个保存所有的数据都不能保存成功,只有当所有的数据都保存成功了才能一次性保存所有数据
首先在页面js头部定义两个全局变量:
//行表添加/修改操作次数
var addFrequance = 0;
//行表添加/修改成功次数
var successFrequance = 0;
只有当操作次数==成功次数的时候,才能统一保存所有数据,此时将save()方法修改如下:
saveFn:function () {
addFrequance++;
var validatorQuaInfo = $("#quaInfoGrid").data("kendoValidator")
if (validatorQuaInfo.validate()) {
quaInfoGrid.saveChanges().done(function (resp) {
if (resp != null){
if (resp.response.success){
successFrequance++;
}
}
}else {
successFrequance++;
}
})
}
},
3、最后在头表的保存按钮中调用所有grid的saveFn()方法,并执行头表中的保存方法
quaInfoViewModel.saveFn();
cusEntpViewModel.saveFn();
manScopeViewModel.saveFn();
diaScopeViewModel.saveFn();
cusPurchViewModel.saveFn();
cusRepoViewModel.saveFn();
if (addFrequance == successFrequance) {
Hap.submitForm({
url: BaseUrl + '/cux/gxp/cus/header/submit',
......
})
)
4、最后关闭Ajax的异步属性,将其设置为同步
由于Hap封装的saveChanges()方法是异步的,那么在执行这几个保存操作的时候无法保存这几个方法按照顺序执行,导致即使操作次数和成功次数实际相等,但是可能在判断的时候这两个参数并不相等,所以会导致点击保存按钮后可以保存行表中的数据,但是不能保存头表中的数据,点击第二下才能保存头表数据
此时需要将savaChanges()方法设置未同步执行即可,但是Hap封装savaChanges()的时候并没有给我们预留设置Ajax异步属性的接口,因此我们只能设置全局属性,将页面上所有的Ajax设置为同步
$.ajaxSetup({
async: false
});
至此,就可以实现头表上一个按钮同时保存头表数据和所有的行表Grid数据了
存在问题
由于这个全局属性将页面上所有的Ajax方法都设置成了同步,可能会影响页面数据处理的性能
希望Hap能提供一个设置Ajax同步属性的接口
网友评论