Форма Symfony – доступ Entity внутри дочерней записи Тип в CollectionType

Я пытаюсь получить доступ к сущности для данной встроенной формы в родительском FormBuilder CollectionType внутри FormBuilder :

ParentType

 Class ParentType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('children', CollectionType::class, array( 'entry_type' => ChildType::class ); } } 

ChildType

 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 объекту внутри ChildType ?

Related of "Форма Symfony – доступ Entity внутри дочерней записи Тип в CollectionType"

Ответ заключается в использовании Event Listeners, которые прослушивают событие 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 } } ); } 

Это более подробное решение на основе 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(), )); }