1

我在我的项目中使用Ajv。我正在尝试在ajv.addKeywordapi 的帮助下添加自定义关键字。我可以通过这样做来添加关键字(从文档中借来的):

var ajv = new Ajv({
  $data: true
});

ajv.addKeyword('range', {
  type: 'number',
  compile: function(sch, parentSchema) {
    var min = sch[0];
    var max = sch[1];
    return parentSchema.exclusiveRange === true ? function(data) {
      return data > min && data < max;
    } : function(data, dataPath, parentData, parentDataProperty) {
      return data >= min && data <= max;
    }
  }
});

var schema = {
  "properties": {
    "smaller": {
      "type": "number"
    },
    "larger": {
      "type": "number",
      "range": [2, 10]
    }
  }
};

var validData = {
  smaller: 15,
  larger: 17
};

let validateData = ajv.compile(schema);
validateData(validData);
console.log('Errors after validations --> ', validateData.errors)

一切正常。现在我需要$data为我的自定义字段使用原因数据将是其他字段的值。为了实现它,这是我尝试使用我的模式:

var schema = {
  "properties": {
    "smaller": {
      "type": "number"
    },
    "larger": {
      "type": "number",
      // "range": [2, 10],
      "range": {
        "$data": "1/myRange" // referencing to myRange
      }
    },
    "myRange": {
      type: "array",
      items: {
        type: "number"
      }
    }
  }
};

但看起来$dataref 尚不支持自定义字段。如文档中所述,$data ref 仅支持以下字段。

关键字中支持 $data 引用:const、enum、format、maximum/minimum、exclusiveMaximum/exclusiveMinimum、maxLength/minLength、maxItems/minItems、maxProperties/minProperties、formatMaximum/formatMinimum、formatExclusiveMaximum/formatExclusiveMinimum、multipleOf、pattern、required、uniqueItems .

获取值的一种方法是,我使用验证函数的参数并编写逻辑来提取refdata, dataPath, parentData, parentDataProperty定义的字段的值。$data但我不确定这是否是实现它的正确方法。谁能帮我解决这个问题?这是玩的plunkr。谢谢。

4

1 回答 1

7

在挖掘文档一段时间后,我终于让它工作了。为后来的读者分享解决方案总是好的。这就是我所做的:

// Code goes here
console.clear();
var ajv = new Ajv({
  $data: true
});


ajv.addKeyword('range', {
  type: 'number',
  errors: true,
  $data: true, // important part
  validate: function(schema, data, parentSchema) {
    const {
      exclusiveRange: isExclusive
    } = parentSchema;
    const [min, max] = schema;
    if (isExclusive) {
      return data > min && data < max;
    }
    return data >= min && data <= max;
  }
});

var schema = {
  "properties": {
    "smaller": {
      "type": "number",
      "maximum": {
        "$data": "1/larger"
      }
    },
    "larger": {
      "type": "number",
      // "range": [2, 10],
      "range": {
        "$data": "1/myRange"
      },
      "exclusiveRange": true
    },
    "myRange": {
      type: "array",
      items: {
        type: "number"
      }
    }
  }
};


var validData = {
  smaller: 3,
  larger: 7,
  myRange: [2, 10]
};

let validateData = ajv.compile(schema);
validateData(validData);
console.log(ajv);
console.log('Errors after validations --> ', validateData.errors)

突出选项$data在定义中。需要设置true。这是工作的plunkr

于 2018-03-16T10:59:17.830 回答