Symfony3 + Select2 AJAX - 禁用选择验证

Symfony3 + Select2 AJAX - disable validation of choices

我有一个带有 ChoiceType 字段的 Symfony3 表单。它使用带有 AJAX 数据源的 Select2。这一点工作正常。然而,当提交表单时,Symfony 验证开始并抱怨:

This value is not valid  

我猜这是因为通过 AJAX 选择的选项在表单类型的 'choices' 键中不存在。

我对 Symfony 比较陌生。有人可以指出正确的方向来禁用字段上的验证吗?

您不应该禁用验证。使用 Form Events - http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html

动态添加选项

您还可以查看此捆绑包:https://github.com/tetranz/select2entity-bundle

您必须始终使用字符串值将数据提交到 ChoiceType

考虑以下 ChoiceType 配置:

use Symfony\Component\Form\Extension\Core\Type\ChoiceType;

$builder->add('some_choice', ChoiceType::class, array(
    'choices' => array(
        'Choose 1' => 1,
        'Choose A' => 'A',
        'Choose True' => true,
    ),
));

默认情况下,您可能希望将选择数组中的每个键用作标签,并且将每个选择值转换为字符串并用作 html 值:

<option value="1">Choose 1</option>
<option value="A">Choose A</option>
<option value="1">Choose True</option>

上面这个例子是错误的。

如您所见,将 true 转换为字符串会得到 "1" 并且它已用于整数 1 选择。

所有选择值必须始终是唯一的,因此默认情况下,在这种情况下,ChoiceType 使用数字递增:

<option value="0">Choose 1</option>
<option value="1">Choose A</option>
<option value="2">Choose True</option>

The same happens when some model choice value in the choice array are not scalar (e.g array, object, null ...).

则提交的数据应为"0""1""2"。每个都将通过 ChoiceType.

映射回相应的选择

为了完全控制用于每个选择的字符串值,您可以使用选项 choice_value 作为闭包,它将每个选择作为唯一参数传递并且必须 return 它的字符串值。

如果您的选择是对象或数组,您可以将其设置为 属性 路径:

'choice_value' => 'property'

// will be equivalent to

'choice_value' => function ($choice) {
    if (is_array($choice)) {
        return $choice['property'];
    }

    if (is_object($choice)) {
        return $choice->getProperty();
        // or even $choice->isProperty()
    }

    throw new UnexpectedTypeException();
}

结论:

默认行为与:

$builder->add('some_choice', ChoiceType::class, array(
    'choices' => array(
        'Choose 1' => 1,
        'Choose A' => 'A',
        'Choose True' => true,
    ),
    'choice_value' => function ($choice) {
        if (!is_scalar($choice) {
            return null;
        }

        return false === $choice ? '0' : (string) $choice;
    },
));

如果 null 或两个相同的值被 returned,将使用递增的整数。

您始终必须提交字符串选择值,才能将其映射回 ChoiceType

任何未知值或 "extra" 值都将导致您的错误。

official doc