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

How to add a calculated field in the FormEvents::PRE_SUBMIT Event

在我的监听器中,我需要在 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);
}

如您所见,它有效。然而,这是一种骇人听闻的方式,我不相信专业人士会这样做。这里有两处错误:

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

使用SUBMIT代替PRE_SUBMIT

不用担心,表单还没有提交,SUBMITForm::submit

之前执行

为什么会遇到这个问题?

PRE_SUBMIT中的所有数据都没有被归一化为您常用的对象...

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

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

我的目标是在表单中显示计算的总计字段。而已。但是在 SUBMIT 事件中你不能做 $form->get('total')->setData($total);。您将收到一条警告:You cannot change the data of a submitted form.

所以在 PRE_SUBMIT 之后改变表格是不可能的。但是添加字段..

我的完整解决方案如下:

在 DayType 表单生成器中:

// 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