为表单事件中的某个表单字段添加模型转换器

时间:2015-08-17 05:20:53

标签: forms symfony

我找到的唯一方法是在表单类型的buildForm方法中添加模型转换器,如下面的代码所示:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $transformer = new IssueToNumberTransformer($entityManager);
    $builder->add(
        $builder->create('issue', 'text')->addModelTransformer($transformer)
    ); 
}

但我有一个表单字段,当另一个表单字段具有有效值时显示,所以我宁愿在FormEvent::PRE_SET_DATA事件中创建表单字段。

1。一个错误的方式

->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($builder) {
     /** @var $order \VMSP\OrderBundle\Entity\OrderInterface */
     $order = $event->getData();
     $form  = $event->getForm();
     /** @var $serviceType \VMSP\StoreBundle\Entity\ServiceType */
     $serviceType = $order->getServiceType();

     //only home service needs user's address
     if ($serviceType && $serviceType->getType() == ServiceType::TYPE_HOME_SERVICE) {
         //won't work
         $form->add(
             $builder->create('address','hidden')
                     ->addModelTransformer($this->addressTransformer),
             array(
                 'label' => 'vmsp_order.contact.form.address',
             )
         );
    }
}

有人建议

$form->add(
   $builder->create('address', 'hidden')
           ->addModelTransformer($this->addressTransformer),
   array( 'label' => 'vmsp_order.contact.form.address')
);

不幸的是,它抛出了这个错误:

  

“string,integer或Symfony \ Component \ Form \ FormInterface”,“Symfony \ Component \ Form \ FormBuilder”类型的预期参数

2。另一种错误的方式

if ($serviceType && $serviceType->getType() == ServiceType::TYPE_HOME_SERVICE) {
    $form->add(
        'address', 
        'hidden', 
        array('label' => 'vmsp_order.contact.form.address')
    );

    $form->get('address')
         ->getConfig()
         ->addModelTransformer($this->addressTransformer);
}

得到错误:

  

将构建器转换为FormConfigInterface实例后,无法再访问FormConfigBuilder方法。

我列出了上面两种错误的方法,因为我发现有很多帖子说这些方法是正确的,当然,它们不是。这篇文章和symfony2-form-events-and-model-transformers 一样是一个问题,但答案不是我需要的,所以我的问题是,在某个表单字段的表单事件中添加模型转换器的方法是什么?

2 个答案:

答案 0 :(得分:0)

我建议在反向模式下进行。配置隐藏的地址字段,如有必要,请稍后将其删除:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $transformer = new IssueToNumberTransformer($entityManager);
    $builder->add(
        $builder->create('issue', 'text')->addModelTransformer($transformer)
    )->add('address','hidden')
     ->addModelTransformer($this->addressTransformer);
}

然后,检查监听器是否应删除隐藏字段:

 ->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($builder) {
     /** @var $order \VMSP\OrderBundle\Entity\OrderInterface */
     $order = $event->getData();
     $form  = $event->getForm();
     /** @var $serviceType \VMSP\StoreBundle\Entity\ServiceType */
     $serviceType = $order->getServiceType();

     //only home service needs user's address
     if (!$serviceType || $serviceType->getType() != ServiceType::TYPE_HOME_SERVICE) {
         //will work
         $form->remove('address');
    }
}

我想知道为什么第一个错误的方法不起作用?出现哪个错误?

答案 1 :(得分:0)

您的“ 1.一种错误方法”不起作用,因为$builder->addModelTransformer()返回了FormConfigBuilderInterface,但是$form->add()期望返回FormInterface(请参见错误消息)。

要使其生效,只需添加 getForm()

$form->add(
    $builder->create('address','hidden')
        ->addModelTransformer($this->addressTransformer)
        ->getForm()   // Creates the form
        ...