简体   繁体   English

如何在静态yup模式中使用动态变量?

[英]How to use a dynamic variable in a static yup schema?

I want to statically create a yup schema (the schema is defined once) that takes a dynamic variable each time it's called (the variable can be different with each call). 我想静态创建一个yup模式(该模式定义一次),每次调用时都要使用一个动态变量(该变量可能随每次调用而不同)。 Is this possible? 这可能吗?

eg, 例如,

// file: schema.js
// create the schema once
yup = require('yup');
const schema = yup.mixed().test(
  'my-test-name',
  'cannot be an existing value',
  value => !myArray.includes(value)  // How to reference myArray here?
       // As written, it results in "ReferenceError: myArray is not defined"
);
module.exports = schema;



// other file that imports the schema:
schema = require('./schema.js');
let myArray = ['blue', 'green'];
schema.validateSync('yellow');  // should pass validation, because 'yellow' not in myArray

myArray = ['orange', 'yellow'];
schema.validateSync('yellow');  // should fail validation, because 'yellow' is in myArray

(I realize it's possible to dynamically create a schema each time with a variable in that scope. However, I'm working in a codebase with many statically-defined yup schemas, with a function mapping the schemas to their corresponding fields. I'm hoping for a way to be able to be able to use dynamic variables for just a couple of those schemas that need them, and not have to modify every static schema to be dynamic.) (我意识到有可能每次在该范围内使用变量来动态创建模式。但是,我正在使用许多静态定义的yup模式在代码库中工作,并且具有将模式映射到其对应字段的函数。希望有一种方法能够将动态变量仅用于需要它们的几个模式,而不必将每个静态模式都修改为动态。)

Try exporting a function that creates a dynamic schema. 尝试导出创建动态架构的函数。 Please see below. 请看下面。

// file: schema.js
// create the schema once
yup = require('yup');

// export as a function
module.exports = myArray => {
  return yup.mixed().test(
    'my-test-name',
    'cannot be an existing value',
    value => !myArray.includes(value)  
  );
};



// other file that imports the schema:
schema = require('./schema.js');
let myArray = ['blue', 'green'];

let blueGreenSchema = schema(myArray);
blueGreenSchema.validateSync('yellow');  

myArray = ['orange', 'yellow'];
let orangeYellowSchema = schema(myArray);
orangeYellowSchema.validateSync('yellow');  

To use a dynamic variable, 3 things are needed: 要使用动态变量,需要三件事:

  1. use the second Options parameter to validateSync() with the context key 使用第二个Options参数validateSync() context密钥validateSync()
  2. declare the .test() function using a function expression, not an arrow function (because yup binds the function to this ) 使用函数表达式而不是箭头函数声明.test()函数(因为yup将函数绑定到this
  3. inside the test function, reference the dynamic variable with this.options.context.variableName 在测试函数中,使用this.options.context.variableName引用动态变量

eg, 例如,

const yup = require('yup');

// statically declare the schema
const schema = yup.mixed().test(
  'my-test-name',
  'cannot be an existing value',  // error message
  function test(value) {
    // NOTE: this must not be an arrow function, because yup binds it to it's "this"
    // Note the use of this.options.context to reference the dynamic variable
    return !this.options.context.myArray.includes(value)  
  }
);

// Note the use of passing a { context: ... } as the second "options" parameter to validateSync()
ret = schema.validateSync('yellow', { context: { myArray: ['blue', 'green'] } } );
console.assert(ret === 'yellow');  // passes validation

    let errorMessage;
try {
  schema.validateSync('blue', { context: { myArray: ['blue', 'green'] } } );
}
catch(error) {
  errorMessage = error.message;
}
console.assert(errorMessage === 'cannot be an existing value');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM