Symfony-Formular – Greifen Sie auf die Entität innerhalb des untergeordneten Eintrags zu. Geben Sie einen CollectionType ein

Lesezeit: 3 Minuten

Benutzer-Avatar
Nick

Ich versuche, auf die Entität für ein bestimmtes eingebettetes Formular im übergeordneten Element zuzugreifen CollectionType Innerhalb 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',
        );
    }
}

Während dies in einer normalen Form funktioniert, $child wird als null zurückgegeben. Wie kann ich auf die zugreifen Child Wesen hinein ChildType?

Benutzer-Avatar
Benutzer1207727

Die Antwort liegt in der Nutzung Ereignis-Listener die auf die hören PRE_SET_DATA Veranstaltung.

Es wird Ihre Schließung passieren a FormEvent Klasse, die sowohl das Formular als auch die daran gebundenen Daten enthält.

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

            }
        }
    );
}

  • Um die offensichtliche Frage zu stellen, haben Sie definitiv Bars in Ihrer Muttergesellschaft, die für die Daten des Formulars verwendet werden? Können Sie Ihre Bars-Sammlung anhand der Daten in Ihrem übergeordneten Formulartyp durch var_dumping überprüfen?

    – Benutzer1207727

    16. März 2012 um 21:10 Uhr

  • Wunderbar, danke! Dies funktionierte perfekt und führte mich auch zu dem Teil in den Dokumenten, den ich übersehen hatte: So generieren Sie Formulare mithilfe von Formularereignissen dynamisch

    – Nick

    16. März 2012 um 21:32 Uhr

  • Fantastisch! Ich bin froh, dass es für Sie funktioniert hat. Einige dieser Dinge können im Vergleich zu Symfony 1 ziemlich mysteriös erscheinen, aber langsam sehe ich das Licht am Ende des Tunnels 🙂

    – Benutzer1207727

    16. März 2012 um 21:37 Uhr

  • Dies funktioniert nicht in Symfony2.6. Es gibt kein DataEvent (Sie können immer noch googeln und eine Seite mit Details der Klasse finden, aber die Klasse ist nicht in Symfony2 enthalten)

    – AntonioCS

    27. Februar 2015 um 12:00 Uhr

  • Auf Symfony 2.6. Ereignisklasse ist Symfony\Component\Form\FormEvent

    – Pawel Dubinin

    1. September 2015 um 19:48 Uhr

Dies ist eine detailliertere Lösung basierend auf user1207727.

Übergeordneter Typ

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
        ));
    }
}

Kindertyp

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',
        ));
    }

}

Formular im Controller erstellen

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(),
    ));
}

1034630cookie-checkSymfony-Formular – Greifen Sie auf die Entität innerhalb des untergeordneten Eintrags zu. Geben Sie einen CollectionType ein

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy