Aurelia自定义验证:点击保存时检查表单是否有变更
解决Aurelia中表单变更验证的问题
看起来你遇到的问题主要有两个关键点:原始对象的引用赋值错误,以及自定义验证规则的逻辑和使用方式不对。我来一步步帮你修正:
1. 首先修复原始对象的保存问题
你现在的代码里this.originalClient === this.client是比较操作,不是赋值,而且就算改成赋值this.originalClient = this.client,也只是把引用指向同一个对象——后续修改this.client时,this.originalClient也会跟着变,根本起不到“保存初始值”的作用。
你需要做的是深拷贝初始对象,确保原始值和当前值是两个独立的对象:
fetch("/api/Client/editClient/" + parms.id, { method: "GET", headers }) .then(response => response.json()) .then(data => { this.client.deserialize(data); // 用JSON序列化/反序列化实现深拷贝(适合简单对象) this.originalClient = JSON.parse(JSON.stringify(this.client)); // 如果是嵌套复杂对象,推荐用lodash的cloneDeep: // this.originalClient = _.cloneDeep(this.client); })
2. 调整自定义验证规则的逻辑
直接用fetchedEntity != value没法正确比较对象(因为是引用类型,哪怕属性值一样,引用不同也会返回true),你需要深比较两个对象的属性值。这里可以用lodash的isEqual方法(如果项目里没有lodash,也可以自己写递归比较函数,不过lodash更省心)。
修改你的自定义规则:
ValidationRules.customRule( 'changesExist', // currentObj是当前要验证的对象,originalObj是我们传入的原始对象 (currentObj, _, originalObj) => { // 反向判断:如果两个对象不相等,说明有变更,验证通过 return !_.isEqual(currentObj, originalObj); }, 'No changes detected' );
3. 正确应用验证规则
你之前的ensure写法有语法错误,应该指定要验证的属性名,然后绑定到当前ViewModel:
// 在ViewModel的构造函数或者初始化方法里定义规则 ValidationRules .ensure('client') // 验证this.client这个属性 .satisfiesRule('changesExist', this.originalClient) .on(this); // 绑定到当前ViewModel实例
4. 在保存按钮的点击事件中触发验证
最后,在保存时调用验证控制器,根据结果决定是否提交:
async saveClient() { // 触发验证 const validationResult = await this.validationController.validate({ object: this.client, rules: ValidationRules }); if (validationResult.valid) { // 验证通过(有变更),提交到服务器 await fetch(`/api/Client/editClient/${parms.id}`, { method: "PUT", headers: { ...headers, 'Content-Type': 'application/json' }, body: JSON.stringify(this.client) }); // 提交成功后的逻辑,比如提示、跳转 alert("Changes saved successfully!"); } else { // 验证不通过(无变更),提示用户 alert("No changes detected - nothing to save!"); } }
这样调整后,就能在前端准确判断表单是否有变更,只有当内容真的修改过才会发起请求到服务器。
内容的提问来源于stack exchange,提问作者si2030
相关产品推荐
相关产品推荐

