Я пытаюсь получить доступ к сущности для данной встроенной формы в родительском 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
?
Ответ заключается в использовании 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(), )); }