根据 FormType 中的另一个选项值定义表单选项允许值
Define a form option allowed values depending on another option value in a FormType
在 Symfony 2.8 中,在自定义表单类型中,是否可以使 setAllowedValues return 的结果取决于另一个选项的值?据我所知,没有明显的方法来访问闭包中的 Options
对象。
public function configureOptions(OptionsResolver $resolver) {
$resolver->setRequired('option1');
$resolver->setRequired('option2');
$resolver->setAllowedValues('option2', function ($value) {
return $based_on_set_restricted_by_option1; // <-- option2 values are allowed or denied depending on what option1 says
}
}
我所拥有的最接近解决方案的想法是拥有一个选项,它是一个封装了选项 1 和选项 2 的字典,并在其上执行 setAllowedValues,但现在重组选项并不容易。
symfony 表单类型的方法 configureOptions()
可以做很多事情,因为它提供了一个 OptionsResolver 对象(依赖于它自己的组件 see)来调整您的配置。
在这种情况下,您需要调用 $resolver->setNormalizer()
(see),这正是您想要的,它需要一个选项来定义,一旦设置了其他选项和一个可调用项。
当解析器规范化您的选项时,它通过将所有选项的数组作为第一个参数传递来执行可调用,并将要规范化的选项的设置值作为第二个参数传递:
// class CustomFormType extends \Symfony\Component\Form\Extension\Core\Type\AbstractType
use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException;
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefault('some_option', 'default value');
// or many at once
$resolver->setDefaults(array(
'some_option' => 0,
'range_condition' => null,
);
// what you need
$someOptionNormalizer = function (Options $options, $someOption) {
$rangeCondition = $options['range_condition'];
if (in_array($rangeCondition, range(2, 5))) {
if (in_array($someOption, range(6, 9))) {
return $someOption;
}
throw new InvalidOptionsException(sprintf('When "range_condition" is inferior or equal to 5, "some_option" should be between 6 and 9, but "%d" given.', $someOption));
}
if (in_array($rangeCondition, range(10, 13))) {
if (in_array($someOption, range(1000, 1005))) {
return $someOption;
}
throw new InvalidOptionsException(sprintf('When "range_condition" is between 10 and 13, "some_option" should be between 1000 and 1005, but "%d" given.', $someOption));
}
};
$resolver->setNormalizer('some_option', $someOptionNormalizer);
// you can also do
$resolver->setRequired('some_option');
$resolver->setAllowedTypes('some_option', array('integer'));
$resolver->setAllowedTypes('range_condition', array('null', 'integer'));
$resolver->setAllowedValues('some_option', array_merge(range(6, 9), range(1000, 1005)));
$resolver->setAllowedValues('range_condition', array_merge(range(2, 5), range(10, 13)));
// ...
}
在 Symfony 2.8 中,在自定义表单类型中,是否可以使 setAllowedValues return 的结果取决于另一个选项的值?据我所知,没有明显的方法来访问闭包中的 Options
对象。
public function configureOptions(OptionsResolver $resolver) {
$resolver->setRequired('option1');
$resolver->setRequired('option2');
$resolver->setAllowedValues('option2', function ($value) {
return $based_on_set_restricted_by_option1; // <-- option2 values are allowed or denied depending on what option1 says
}
}
我所拥有的最接近解决方案的想法是拥有一个选项,它是一个封装了选项 1 和选项 2 的字典,并在其上执行 setAllowedValues,但现在重组选项并不容易。
symfony 表单类型的方法 configureOptions()
可以做很多事情,因为它提供了一个 OptionsResolver 对象(依赖于它自己的组件 see)来调整您的配置。
在这种情况下,您需要调用 $resolver->setNormalizer()
(see),这正是您想要的,它需要一个选项来定义,一旦设置了其他选项和一个可调用项。
当解析器规范化您的选项时,它通过将所有选项的数组作为第一个参数传递来执行可调用,并将要规范化的选项的设置值作为第二个参数传递:
// class CustomFormType extends \Symfony\Component\Form\Extension\Core\Type\AbstractType
use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException;
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefault('some_option', 'default value');
// or many at once
$resolver->setDefaults(array(
'some_option' => 0,
'range_condition' => null,
);
// what you need
$someOptionNormalizer = function (Options $options, $someOption) {
$rangeCondition = $options['range_condition'];
if (in_array($rangeCondition, range(2, 5))) {
if (in_array($someOption, range(6, 9))) {
return $someOption;
}
throw new InvalidOptionsException(sprintf('When "range_condition" is inferior or equal to 5, "some_option" should be between 6 and 9, but "%d" given.', $someOption));
}
if (in_array($rangeCondition, range(10, 13))) {
if (in_array($someOption, range(1000, 1005))) {
return $someOption;
}
throw new InvalidOptionsException(sprintf('When "range_condition" is between 10 and 13, "some_option" should be between 1000 and 1005, but "%d" given.', $someOption));
}
};
$resolver->setNormalizer('some_option', $someOptionNormalizer);
// you can also do
$resolver->setRequired('some_option');
$resolver->setAllowedTypes('some_option', array('integer'));
$resolver->setAllowedTypes('range_condition', array('null', 'integer'));
$resolver->setAllowedValues('some_option', array_merge(range(6, 9), range(1000, 1005)));
$resolver->setAllowedValues('range_condition', array_merge(range(2, 5), range(10, 13)));
// ...
}