Symfony 表单 - 在 CollectionType 中的子条目类型中访问实体
Posted
技术标签:
【中文标题】Symfony 表单 - 在 CollectionType 中的子条目类型中访问实体【英文标题】:Symfony form - Access Entity inside child entry Type in a CollectionType 【发布时间】:2012-04-01 04:42:24 【问题描述】:我正在尝试访问 FormBuilder
内的父 CollectionType
中给定嵌入表单的实体:
父类型
Class ParentType extends AbstractType
public function buildForm(FormBuilderInterface $builder, array $options)
$builder->add('children', CollectionType::class, array(
'entry_type' => ChildType::class
);
子类型
class ChildType extends AbstractType
public function buildForm(FormBuilderInterface $builder, array $options)
$child = $builder->getData(); // this returns null
public function getDefaultOptions(array $options)
return array(
'data_class' => 'Vendor\Bundle\Entity\Child',
);
虽然这在正常形式下工作,但 $child
被返回为 null。如何访问ChildType
中的Child
实体?
【问题讨论】:
【参考方案1】:答案在于使用事件监听器来监听PRE_SET_DATA
事件。
它将向您的闭包传递一个 FormEvent
类,其中包含表单和绑定到它的数据。
public function buildForm(FormBuilderInterface $builder, array $options)
$builder->addEventListener(FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($builder)
$form = $event->getForm();
$child = $event->getData();
if ($child instanceof Child)
// Do what ever you like with $child entity data
);
【讨论】:
要问一个显而易见的问题,您的父实体中是否肯定有任何用于表单数据的 Bars?您可以通过 var_dumping 您的父表单类型中的数据来检查 bar 集合吗? 太好了,谢谢!这非常有效,也让我找到了我忽略的文档中的部分:How to Dynamically Generate Forms Using Form Events 太棒了!我很高兴它对你有用。与 symfony 1 相比,其中一些东西看起来相当神秘,但慢慢地我开始看到隧道尽头的曙光 :) 这在 Symfony2.6 中不起作用。没有 DataEvent (你仍然可以 google 并找到一个包含课程详细信息的页面,但该课程不包含在 Symfony2 中) 在 symfony 2.6 上。事件类是Symfony\Component\Form\FormEvent
【参考方案2】:
这是基于user1207727的更详细的解决方案。
父类型
class FrontentStatsInputFormType extends AbstractType
public function buildForm(FormBuilderInterface $builder, array $options)
$builder
->add('records', CollectionType::class, array(
'entry_type' => FrontendStatsRecordType::class,
'allow_add' => false,
'allow_delete' => false,
'label' => null,
))
;
public function configureOptions(OptionsResolver $resolver)
$resolver->setDefaults(array(
'data_class' => null
));
儿童类型
class FrontendStatsRecordType extends AbstractType
public function buildForm(FormBuilderInterface $builder, array $options)
$builder->addEventListener(FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($builder)
$form = $event->getForm();
$child = $event->getData();
if ($child instanceof StatsRecord)
// Do what ever you like with $child entity data
// $child->getSomeValue();
$form->add('value', TextType::class);
);
public function configureOptions(OptionsResolver $resolver)
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\StatsRecord',
));
在控制器中创建表单
public function indexAction(Request $request, InputForm $inputForm)
$data = array();
foreach ($inputForm->getStatsTemplates() as $template)
$statsRecord = new StatsRecord();
$data['records'][] = $statsRecord;
$form = $this->createForm('AppBundle\Form\FrontentStatsInputFormType', $data);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid())
$em = $this->getDoctrine()->getManager();
// Get entries and persist them in the database
$records = $form->get('records')->getData();
foreach ($records as $record)
$em->persist($record);
$em->flush();
return $this->redirectToRoute('frontend_index');
return $this->render('frontend/showInputForm.html.twig', array(
'inputForm' => $inputForm,
'form' => $form->createView(),
));
【讨论】:
以上是关于Symfony 表单 - 在 CollectionType 中的子条目类型中访问实体的主要内容,如果未能解决你的问题,请参考以下文章
Symfony / Sonata Admin:编辑表单上的列表表单