【问题标题】:How to use a dynamic variable in a static yup schema?如何在静态 yup 模式中使用动态变量?
【发布时间】:2019-03-14 23:07:40
【问题描述】:

我想静态地创建一个 yup 模式(模式定义一次),每次调用时都会使用一个动态变量(每次调用的变量可能不同)。这可能吗?

例如,

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

(我意识到每次都可以使用该范围内的变量动态创建模式。但是,我正在使用具有许多静态定义的 yup 模式的代码库,并使用函数将模式映射到其相应的字段。我希望有一种方法能够将动态变量用于其中几个需要它们的模式,而不必将每个静态模式都修改为动态的。)

【问题讨论】:

标签: javascript node.js yup


【解决方案1】:

要使用动态变量,需要做 3 件事:

  1. 将第二个Options 参数与validateSync() 结合使用context
  2. 使用函数表达式声明.test() 函数,而不是箭头函数(因为yup 将函数绑定到this
  3. 在测试函数内部,用this.options.context.variableName引用动态变量

例如,

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');

【讨论】:

    【解决方案2】:

    尝试导出一个创建动态架构的函数。请看下文。

    // 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');  
    

    【讨论】:

    • 是的,我意识到这是另一种选择。但是,我正在使用许多静态定义的 yup 模式的代码库,并映射到它们的相应字段。我希望有一种方法能够将动态变量仅用于几个需要它们的模式,而不必将每个静态模式都修改为动态的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-06
    • 2010-11-26
    • 2015-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-11
    相关资源
    最近更新 更多