Symfony2表单 - 嵌入表单上的事件监听器

时间:2013-11-18 19:03:53

标签: forms symfony symfony-2.3

从symfony cookbook中关于动态表单生成的示例开始(link to doc

class SportMeetupType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('sport', 'entity', array(...))
        ;

        $builder->addEventListener(
            FormEvents::PRE_SET_DATA,
            function(FormEvent $event) {
                $form = $event->getForm();

                // this would be your entity, i.e. SportMeetup
                $data = $event->getData();

                $positions = $data->getSport()->getAvailablePositions();

                $form->add('position', 'entity', array('choices' => $positions));
            }
        );
    }
}

我重复了这段代码的不同之处,我将这个表单嵌入到父表单中(称为例如SportPlayerType)。

SportPlayerType映射到实体SportPlayer,其中包含几个属性:$ name和$ meetup,一个字符串和一个SportMeetup。

我的问题在于lambda函数,addEventListener的参数:

  • $event->getForm()返回子表单SportMeetupType
  • $event->getData()返回父映射实体SportPlayer

因此,$form->add('position')会抛出错误,因为FormBuilder无法与实体SportPlayer上的position字段匹配。

当嵌入表格中的SportMeetupType时,如何强制SportMeetupType和实体SportMeetup之间的匹配?

1 个答案:

答案 0 :(得分:1)

我们有理由将事件称为PRE_SET_DATA ...

即在设置提交的数据之前,事件被触发

因此您无法访问......

$event->getData()->getSport();
只要在创建表单时没有提供new Sport()对象或现有实体,即在控制器中,

...在监听器中:

$entity = new Sport(); // ... or get the entity from db
$form = $this->createForm(new SportMeetupType(), $entity);

只需使用POST_SET_DATA event,即可获得数据。