如何在FormEvents :: PRE_SUBMIT事件中添加计算字段

时间:2016-07-11 13:03:28

标签: events listener symfony-forms symfony

在我的监听器中,我需要在FormEvents::PRE_SUBMIT事件中访问我的实体。在POST_SET_DATA这没问题,只需使用$event->getData();

因此,对于收听POST_SET_DATA的事件,我对此代码很满意:

public function postSetData(FormEvent $event)
{
    $form = $event->getForm();
    $day = $event->getData();
    $total = $this->dayManager->calculateTotal($day); // Passing a Day object, yay!

    $form->get('total')->setData($total);
}

然而,在PRE_SUBMIT事件的方法中。

我需要此功能,因为在提交时,不会使用新提交的数据计算总数。

public function preSubmit(FormEvent $event)
{
    $form = $event->getForm();

    // $day = $event->getData();
    // Raw array because $event->getData(); holds the old not updated Day object
    $day = $form->getData(); 

    // Ough! Had to create and call a seperate function on my dayManager that handles the raw event array
    $total = $this->dayManager->calculateTotalFromArray($event->getData());

    // Modify event data
    $data = $event->getData();

    // Ough(2)! Have to do nasty things to match the raw event array notation
    $totalArray = array( 
       'hour' => $total->format('G') . "", 
       'minute' => intval($total->format('i')) . ""
    );
    $data['total'] = $totalArray;
    $event->setData($data);
}

如您所见,它有效。然而,这是一种如此神圣的方式,我不相信专业人士这样做。这里出了两件事:

  • 无法在Day函数
  • 中使用实体preSubmit对象
  • 必须在calculateTotalFromArray
  • 中创建dayManager功能
  • preSubmit函数
  • 中的原始事件数组匹配的丑陋代码

所以主要问题:如何从Day表单事件中的表单中获取更新的PRE_SUBMIT对象。

2 个答案:

答案 0 :(得分:2)

使用 SUBMIT 代替 PRE_SUBMIT

不用担心,表单尚未提交,SUBMIT会在Form::submit之前执行

你为什么遇到这个问题?

PRE_SUBMIT中的所有数据都没有标准化为您的常用对象......

如果您想了解有关整件事的更多信息,请前往:http://symfony.com/doc/current/components/form/form_events.html

答案 1 :(得分:0)

感谢@galeaspablo提交答案!但是我在下面的代码中添加了如何解决我的特定问题。

我的目标是在表单中显示计算的总字段数。而已。但是,在SUBMIT事件中,您无法执行$form->get('total')->setData($total);。您会收到警告:You cannot change the data of a submitted form.

因此无法在PRE_SUBMIT之后更改表单。但添加字段 ..

我的完整解决方案如下:

在DayType formbuilder中:

// Will add total field via subscriber
//->add('total', TimeType::class, ['mapped' => false])

如果订阅者:

class CalculateDayTotalFieldSubscriber implements EventSubscriberInterface
{

    private $dayManager;

    public function __construct(DayManager $dayManager)
    {
        $this->dayManager = $dayManager;
    }

    public static function getSubscribedEvents()
    {
        return array(
            FormEvents::SUBMIT => 'addTotalField',
            FormEvents::POST_SET_DATA => 'addTotalField'
        );
    }


    public function addTotalField(FormEvent $event)
    {
        $form = $event->getForm();
        $day = $event->getData();

        $total = $this->dayManager->calculateTotal($day);
        $form->add('total', TimeType::class, ['mapped' => false, 'data' => $total]);
    }
}

请注意SUBMITPOST_SET_DATA事件使用保存功能。好的阅读是:http://symfony.com/doc/current/components/form/form_events.html