如何在实例化Mongoose Schema时触发校验 无需调用save()方法
Mongoose 实例化模型时主动触发校验的方案
Mongoose 默认不会在模型实例化阶段执行Schema校验规则,校验逻辑默认仅在调用save()方法、或者执行更新操作前自动触发,要在实例化时就触发校验,直接调用Mongoose模型实例内置的校验方法即可。
具体实现方式
方法1:实例化后手动调用同步校验方法validateSync()
该方法为同步方法,校验失败时会直接返回错误对象,不需要异步等待,适合在同步流程中使用,修改你的循环代码如下:
body.forEach((data) => { element = new FormAttributeElement({ elementTitle: data.elementTitle, datatype: data.datatype, attributeName: data.elementTitle, isRequired: data.isRequired, HTMLInputType: data.HTMLInputType, }); // 主动触发全量Schema校验,包含必填、枚举、自定义校验规则都会执行 const validateErr = element.validateSync(); if (validateErr) { // 校验不通过直接抛出错误,也可以根据业务逻辑做自定义处理 throw validateErr; } formElements.push(element); });
方法2:实例化后调用异步校验方法validate()
该方法为异步方法,返回Promise,适合在异步流程中使用,需要把循环改为支持异步的for...of写法:
// 注意外层函数需要有async标识 for (const data of body) { element = new FormAttributeElement({ elementTitle: data.elementTitle, datatype: data.datatype, attributeName: data.elementTitle, isRequired: data.isRequired, HTMLInputType: data.HTMLInputType, }); // 异步校验,校验失败直接抛出错误 await element.validate(); formElements.push(element); }
进阶:封装自动校验的实例化方法
如果需要每次实例化都自动触发校验,可以给Schema扩展静态工厂方法,避免重复写校验逻辑:
// 在formAttributeElementSchema定义后、导出前添加静态方法 formAttributeElementSchema.statics.newValidatedInstance = async function (data) { const instance = new this(data); await instance.validate(); return instance; } // 后续使用时直接调用即可 const element = await FormAttributeElement.newValidatedInstance(/* 传入参数 */);
额外注意事项
你当前代码中DynamicFormDetail的formShape字段校验存在逻辑错误:运算符优先级导致!formShape[i] instanceof FormAttributeElement永远返回false,正确的写法应该是添加括号调整优先级:
validator: (formShape) => { for (let i = 0; i < formShape.length; i += 1) { // 修正优先级问题,先判断instanceof再取反 if (!(formShape[i] instanceof FormAttributeElement)) return false; } return true; },
内容的提问来源于stack exchange,提问作者Lucky Akbar
相关产品推荐
相关产品推荐

