在ajv实例初始化时,可以调用addKeyword方法来添加自定义关键字,并在处理程序中使用context.instancePath和context.parentData来跟踪触发自定义关键字的次数。
下面是一个示例代码:
const Ajv = require('ajv');
const ajv = new Ajv();
ajv.addKeyword('uniqueName', {
validate: function(schema, data, parentSchema, context) {
const uniqueNames = context.parentData.map(item => item.name);
const nameIndex = uniqueNames.indexOf(data.name);
if (nameIndex !== -1 && nameIndex !== context.parentData.findIndex(item => item.name === data.name)) {
// Duplicate name found
context.parentData[nameIndex].error = 'Duplicate name';
data.error = 'Duplicate name';
return false;
}
return true;
},
errors: true
});
const schema = {
type: 'array',
items: {
type: 'object',
properties: {
name: { type: 'string' }
},
// Adding our custom keyword
uniqueName: true
}
};
const data = [
{ name: 'Alice' },
{ name: 'Bob' },
{ name: 'Alice' }
];
const validate = ajv.compile(schema);
console.log(validate(data));
console.log(data);
在上面的示例中,我们定义了一个自定义关键字uniqueName用于确保数组对象中的每个名称都是唯一的。我们使用context.parentData和context.instancePath来跟踪数组对象中的对象,并通过在对象上设置error属性来标记重复的名称。最后,我们在处理程序中返回false来指示存在错误。为了更好的错误检测,我们还将errors选项设置为true。
最后,我们编译架构并验证数据。当我们运行代码时,我们可以看到以下输出:
false
[
{ name: 'Alice', error: 'Duplicate name' },
{ name: 'Bob' },
{ name: 'Alice', error: 'Duplicate name' }
]
我们可以看到,在第一个和第三个对象中的名称重复,而第二个对象没有错误。