【问题标题】:Ajv: How to leverage $data reference with custom keyword?Ajv:如何利用自定义关键字的 $data 引用?
【发布时间】:2018-08-25 05:01:35
【问题描述】:

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

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"
      }
    }
  }
};

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

关键字支持$data引用:const, enum, format, 最大/最小,排他最大/排他最小,最大长度/ minLength, maxItems / minItems, maxProperties / minProperties, formatMaximum / formatMinimum, formatExclusiveMaximum / formatExclusiveMinimum、multipleOf、pattern、required、uniqueItems。

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

【问题讨论】:

  • 听起来这是一个功能请求。文档说你不能做你要求做的事情。我建议你在项目 github repo 上提出问题。
  • 我想我已经接近解决方案了。我得到了数据表达式。我只需要评估它。这是 plunker plnkr.co/edit/uuA8H08ER1bqrp8nrTU7?p=preview 我正在寻找 Ajv 中的功能。如果您有任何想法,请提出建议。而且,一旦我完成了它,我会提出一个功能请求。如果可能,也提交 PR。

标签: json jsonschema json-schema-validator ajv


【解决方案1】:

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

// 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

【讨论】:

    猜你喜欢
    • 2017-08-06
    • 2018-05-17
    • 1970-01-01
    • 1970-01-01
    • 2019-10-31
    • 2012-03-14
    • 2021-07-04
    • 1970-01-01
    • 2021-07-09
    相关资源
    最近更新 更多