Я хочу статически создать схему 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
(Я понимаю, что каждый раз можно динамически создавать схему с переменной в этой области. Однако я работаю в кодовой базе со многими статически определенными схемами да, с функцией, сопоставляющей схемы с соответствующими полями. Я надеясь найти способ иметь возможность использовать динамические переменные только для пары тех схем, которые в них нуждаются, и не изменять каждую статическую схему, чтобы она была динамической.)



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Попробуйте экспортировать функцию, которая создает динамическую схему. См. Ниже.
// 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');
Чтобы использовать динамическую переменную, необходимы 3 вещи:
Options для validateSync() с ключом context.test(), используя выражение функции, а не функцию стрелки (потому что да, функция связывает функцию с this)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');
Да, я понимаю, что это альтернатива. Однако я работаю с кодовой базой со многими статически определенными схемами «да» с сопоставлением с соответствующими полями. Я надеюсь найти способ иметь возможность использовать динамические переменные только для пары тех схем, которые в них нуждаются, и не изменять каждую статическую схему, чтобы она была динамической.