ExtJS中如何通过Ajax验证明细Store记录并控制保存按钮
解决方案
我来帮你梳理下这个需求的核心解决思路哈——你遇到的关键问题是Ajax请求是异步执行的,直接循环调用的话没法同步等待所有请求返回结果再判断是否禁用保存按钮。这里用Promise来包装每个Ajax请求,再通过Promise.all统一管理所有异步操作,是最稳妥的处理方式。
完整实现步骤及代码
- 绑定保存按钮点击事件:在表头Panel的保存按钮点击逻辑里,先获取表头JDE值和明细Store的所有记录
- 把Ajax请求包装成Promise:将每条明细记录的验证请求转换成Promise对象,方便后续批量处理
- 批量等待所有请求完成:用
Promise.all等待所有验证请求结束,再统一检查结果 - 根据结果控制保存状态:只要有一条记录返回空数据,就禁用保存按钮并提示;所有验证通过再执行保存逻辑
// 假设这是表头保存按钮的点击事件处理函数 onHeaderSaveClick: function() { var me = this; // 获取表头的JDE值(根据你的实际组件引用调整) var jde = me.lookupReference('headerJdeField').getValue(); // 获取明细Grid对应的Store var detailStore = me.lookupReference('detailGrid').getStore(); var submitBtn = me.lookupReference('submit'); // 先重置按钮状态,避免之前的禁用状态影响新操作 submitBtn.enable(); // 处理明细为空的情况(可根据你的需求调整逻辑) if (detailStore.getCount() === 0) { Ext.Msg.alert('提示', '没有明细记录需要验证'); return; } // 加遮罩防止用户重复操作 me.getView().up('panel').ownerCt.mask('正在验证明细参考编号...'); // 遍历明细记录,把每条的Ajax请求包装成Promise var validationPromises = detailStore.getRange().map(function(record) { var refNo = record.get('customerInvoiceDebitNo'); // 对应你的REFNo字段 return new Promise(function(resolve) { Ext.Ajax.request({ url: webContext + '/services/adjustment/accountsreceivableledger', timeout: 120000, method: 'GET', params: { addressNumber: jde, documentNumber: refNo }, success: function(response) { var returnedValue = Ext.decode(response.responseText); // 标记这条记录是否验证通过(非空即为有效) resolve({ refNo: refNo, isValid: returnedValue.data != null && returnedValue.data.length > 0 }); }, failure: function() { // 请求失败也视为验证不通过,可根据需求调整提示 Ext.Msg.alert('错误', '参考编号 ' + refNo + ' 验证请求失败'); resolve({ refNo: refNo, isValid: false }); } }); }); }); // 等待所有验证请求完成后统一处理 Promise.all(validationPromises).then(function(results) { me.getView().up('panel').ownerCt.unmask(); // 检查是否存在验证不通过的记录 var hasInvalid = results.some(function(result) { return !result.isValid; }); if (hasInvalid) { submitBtn.disable(); Ext.Msg.alert('提交错误', '存在无效的明细参考编号(无返回数据)'); } else { // 所有验证通过,执行表头+明细的保存逻辑 Ext.Msg.alert('验证通过', '所有参考编号有效,即将执行保存'); // 这里添加你的保存代码 } }).catch(function(error) { me.getView().up('panel').ownerCt.unmask(); Ext.Msg.alert('异常', '验证过程中发生未知错误'); console.error(error); }); }
关键细节说明
- Promise解决异步同步问题:原来的Ajax是异步执行的,直接循环调用无法确保所有请求完成后再判断结果,用Promise可以把每个请求的结果统一收集后处理。
Promise.all批量处理:它会等待所有Promise都执行完成后才进入then回调,这样就能一次性校验所有明细的验证结果。- 用户体验优化:验证过程中添加遮罩,避免用户重复点击;每次点击保存先重置按钮状态,防止历史状态干扰。
内容的提问来源于stack exchange,提问作者Sweety
相关产品推荐
相关产品推荐

