第三天我一直在受苦,我不知道如何将表单事件侦听器应用于集合。数据会根据用户输入动态变化。该表单包含一个包含用户填写字段的数据的集合。为了动态地改变数据,我使用了事件POST_SET,PRE_SUBMIT同时它POST_SET使用了一个 bang,但是在提交表单之后使用事件,这是一个问题。
在事件中PRE_SUBMIT,我遍历表单的所有集合并获取我可以更改的集合字段。只是这里的问题是,在使用集合时,它们的初始化发生在事件期间SUBMIT,也就是说,PRE_SUBMIT它们根本还没有在表单中!SUBMIT如果你使用or来改变 event POST_SUBMIT,那么集合已经在表单中了,但是它不能再被改变,因为在这个阶段它已经被初始化了。
因此,结果变成了一个恶性循环,PRE_SUBMIT您可以更改这些集合,但它们还不存在,但SUBMIT它们存在,但您无法更改它们。为清晰起见的示例代码:
public function preSubmit(FormEvent $event)
{
$data = $event->getData();
$form = $event->getForm();
// We don`t need to change locations in add event only for update existed
$client = $form->getConfig()->getOptions()['client'];
$shareForms = $form->get('shares');
foreach ($data['shares'] as $key => $share) {
if ($share['pickUpDay'] !== null && $share['pickUpDay'] !== '') {
$locations = $this->em->getRepository('AppBundle:Member\Location')->getLocationsByDay($client, $share['pickUpDay']);
$this->addLocationField($shareForms->get($key), $locations);
}
}
}
我无法在preSubmit方法中获取集合的实例,但我可以,但无法再更改那里的字段。也许有人遇到过?$shareForms->get($key)postSubmit
事件,旨在更改数据。尝试像这样更改它: $event->setData();
结果证明,该解决方案非常简单且合乎逻辑。当需要为集合实例更改和设置值时,监听器必须不是分配给父窗体,而是直接分配给集合实例窗体。
换句话说,如果我们有一个带有集合的表单:
我们不是在这里分配监听器,而是直接在表单类中分配,在entry_type中指定:
因此,集合实例上的事件将自动触发,并且不需要循环。