【问题标题】:Unable to use Callback assert with a form without data_class无法将回调断言与没有 data_class 的表单一起使用
【发布时间】:2017-08-13 14:40:13
【问题描述】:

我正在创建一个名为 IntervalType 的自定义 FormType。我的 IntervalType 将有两个字段,startend,并且是整数类型。此自定义 FormType 将始终在没有 data_class 的情况下使用。

我想添加一个约束来保证start 低于end

如何在没有data_class 的情况下直接在 FormType 中使用 Symfony\Component\Validator\Constraints\Callback?

这是我的IntervalType,仅供参考:

// src/AppBundle/Form/Type/IntervalType.php
namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Validator\Constraints\NotBlank;

class TaskType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('start', IntegerType::class, array(
                'constraints' => array(
                    new NotBlank(),
                ),
            ))
            ->add('end', IntegerType::class, array(
                'constraints' => array(
                    new NotBlank(),
                ),
            ))
        );
    }
}

【问题讨论】:

    标签: symfony symfony-forms symfony-validator


    【解决方案1】:

    当表单不使用任何 data_class 时,唯一的选择似乎是回调约束。

    namespace AppBundle\Form;
    
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\Form\Extension\Core\Type\SubmitType;
    use Symfony\Component\Form\Extension\Core\Type\IntegerType;
    use Symfony\Component\Validator\Constraints\Callback;
    use Symfony\Component\Validator\Constraints\NotBlank;
    use Symfony\Component\Validator\Context\ExecutionContextInterface;
    
    class IntervalType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('start', IntegerType::class, array(
                    'constraints' => array(
                        new NotBlank(),
                    ),
                ))
                ->add('end', IntegerType::class, array(
                    'constraints' => array(
                        new NotBlank(),
                        new Callback(array($this, 'validateInterval')),
                    ),
                ))
                ->add('submit', SubmitType::class);
        }
    
        public function validateInterval($value, ExecutionContextInterface $context)
        {
            $form = $context->getRoot();
            $data = $form->getData();
    
            if ($data['start'] >= $value) {
                $context
                    ->buildViolation('The end value has to be higher than the start value')
                    ->addViolation();
            }
        }
    }
    

    【讨论】:

    • 它可以正常工作。当我将 IntervalType 嵌入到另一个表单中时,它会失败,因为 $context->getRoot() 返回根表单,所以 $data['start'] 不存在。
    • $form = $context->getRoot() 正是我所需要的!谢谢!
    • 您也可以使用$form = $context->getObject()->getParent();,其中$context->getObject() 将是分配回调断言的字段的FormInterface。这在使用嵌入式表单集合时非常有用,可返回包含字段的 FormInterface 对象,而不是顶级(根)FormInterface
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-31
    • 1970-01-01
    • 1970-01-01
    • 2016-03-22
    • 2014-04-21
    相关资源
    最近更新 更多