1

我有一个案例,我们为体育赛事创建注册。

注册包含特定于每项运动的一些字段。其中一些将被类似命名,尽管它们对于每项运动都会有所不同。示例:“球场上最喜欢的位置”:

对于篮球,它将是以下之间的选择领域:

  • 控球后卫
  • 得分后卫
  • ETC...

对于棒球,这将是相同的选择字段,但有一些不同的选择:

  • 投手
  • 内场
  • 外场
  • ...

首次创建表单(用于显示)时,运动作为注册数据的一部分传递:

$registration = new Registration;
$registration->setEvent($event);

并将$event->getSport();为该赛事归还这项运动。

到目前为止一切顺利,并为我的表单生成添加了一个监听器,我只能设置特定于该运动的字段:

public static function getSubscribedEvents()
{
    return [FormEvents::POST_SET_DATA => 'preSetData'];
}

/**
 * @param event DataEvent
 */
public function preSetData(DataEvent $event)
{
    $form = $event->getForm();

    if (null === $event->getData()) {
        return;
    }

    // (The get event here means the real life sports gathering)
    $sport = $event->getData()->getEvent()->getSport();
    /**
     * Then I customize the fields depending on the current sport
     */
}

当用户提交此表单时,问题就出现了。在这种情况下,$event->getData()->getEvent()null

“事件”(现实生活中的一个)是document_id注册表单中的一个字段(此处使用 MongoDB)。

如果我听::BIND事件而不是::PRE_SET_DATA,那么我可以访问所有内容,但是自定义表单已经太晚了,因为它已经绑定了。::PRE_BIND做同样的事情::PRE_SET_DATA

如何在此处正确检索我的赛事和运动文件,以便自定义我的表格并适当地验证它?

4

2 回答 2

0

Why would you need an event to do such task? You can define the fields in the buildForm() action of the form class. To access the event object simply use $options['data']->getEvent()

于 2012-10-29T08:04:50.810 回答
0

所以......终于找到了如何正确地做到这一点。它需要订阅两个不同的事件。

第一次构建表单时,会将一些数据传递给它,因此,PRE_SET_DATA事件包含该数据并且一切正常,如问题中所述。

在提交表单的那一刻,它首先创建时没有数据,因此访问的数据PRE_SET_DATA将为空。在这种情况下,我们跳过表单自定义:

public function preSetData(DataEvent $event)
{
    $myEvent = $event->getData()->getEvent();

    if (null === $myEvent) {
        return;
    }

    $this->customizeForm();
}

这确保了我们在提交表单时不会遇到问题并且没有传递任何数据,但是getData()将返回一个空对象而不是 NULL。

现在,当表单提交时,我们将它绑定到接收到的数据。这就是我们想要干预的时候。因此,我们还将订阅该PRE_BIND事件:

public static function getSubscribedEvents()
{
    return [
        FormEvents::PRE_BIND => 'preBind',
        FormEvents::PRE_SET_DATA => 'preSetData',
    ];
}

在预绑定中,我们收到的数据只是一个值数组,而不是对象图。但是如果我们将对象管理器注入到我们的监听器中,那么我们可以找到我们的对象并使用它们:

public function preBind(DataEvent $event)
{
    $data = $event->getData();
    $id = $data['event'];
    $myEvent = $this->om
                ->getRepository('Acme\DemoBundle\Document\Event')
                ->find(new \MongoId($id));
    if($myEvent === null){
        $msg = 'The event %s could not be found';
        throw new \Exception(sprintf($msg, $id));
    }

    $this->customizeForm();
}
于 2012-10-30T06:11:26.027 回答