Intereting Posts
Длительный опрос блокирует другие вызовы AJAX как сохранить созданный контент DOMPDF в файл? Как я могу использовать .htaccess, чтобы скрыть расширения URL-адресов ?php? Каков наилучший способ преобразования существующего PHP-класса в Java? Отчет, подготовленный PDO для обновления, не работает должным образом PHP-сессии, не работающие на сервере Доступ к статическому объекту с помощью имени переменной Статус доставки AWS SNS php-скрипт останавливается через 360 секунд и показывает 500 ошибок сервера для больших файлов Могу ли я иметь несколько $ _GET с одним и тем же ключом, разные значения? Исключить исключение «Исключение» с сообщением «Сериализация« SimpleXMLElement »не допускается» PHP и запланированные задачи Разрешить отправку пользователем HTML в PHP PHP, получение переменной из другого php-файла как я могу публиковать внешнюю форму с помощью PHP?

Symfony2 с двумя вложенными динамическими полями формы

У меня есть форма Symfony2 с двухслойными динамическими полями. Первый слой не представляет проблемы с документированным способом с событиями формы: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#dynamic-generation-for-submitted-forms

Но затем появляется третье поле, которое зависит от второго поля, которое уже является динамическим полем.

Чтобы продемонстрировать эту проблему, вот мой лишенный код:

<?php class ServiceeventType extends AbstractType { /** * @param FormBuilderInterface $builder * @param array $options */ public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('park', 'entity', array( 'class' => 'AppBundle:Park', 'property' => 'identifyingName', 'label' => 'Park', 'required' => true, 'invalid_message' => 'Choose a Park', 'placeholder' => 'Please choose', )) // just a placeholder for the $builder->get('facility')->addEventListener to have something to bind to // I'm aware, that this is just a symptom of my problem ->add('facility', 'choice', array( 'choices' => array(), 'expanded' => true, 'multiple' => false, 'label' => 'Facility', 'required' => false, 'invalid_message' => 'Choose a Park first', 'placeholder' => 'Please choose a Park first', )) // other fields ; $formModifierPark = function (FormInterface $form, Park $park = null) { // overwrite the facility field with the desired entity type $form->add('facility', 'entity', array( 'class' => 'AppBundle:Facility', 'property' => 'identifyingName', 'choices' => null === $park ? array() : $park->getFacilities(), 'label' => 'Facility', 'required' => true, 'invalid_message' => 'Choose a Facility', 'placeholder' => null === $park ? 'Please choose a Park first' : 'Please choose', )); }; $formModifierFacility = function (FormInterface $form, Facility $facility = null) { $form->add('facilityStatuscode', 'entity', array( 'class' => 'AppBundle:FacilityStatuscode', 'property' => 'identifyingName', 'choices' => null === $facility ? array() : $facility->getFacilityStatuscodeType()->getFacilityStatuscodes(), 'label' => 'Statuscode', 'required' => null === $facility ? false : true, 'invalid_message' => 'Choose a Statuscode', 'placeholder' => null === $facility ? 'Please choose a Facility first' : 'Please choose', )); }; $builder->addEventListener( FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($formModifierPark) { $formModifierPark($event->getForm(), $event->getData()->getPark()); } ); $builder->get('park')->addEventListener( FormEvents::POST_SUBMIT, function (FormEvent $event) use ($formModifierPark) { $formModifierPark($event->getForm()->getParent(), $event->getForm()->getData()); } ); $builder->addEventListener( FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($formModifierFacility) { $formModifierFacility($event->getForm(), $event->getData()->getFacility()); } ); $builder->get('facility')->addEventListener( FormEvents::POST_SUBMIT, function (FormEvent $event) use ($formModifierFacility) { $formModifierFacility($event->getForm()->getParent(), $event->getForm()->getData()); } ); } // more code } 

Проблема заключается в следующем:

Набор событий-слушателей с $builder->get('facility')->addEventListener(FormEvents::POST_SUBMIT,… теряется на данный момент, поле объекта перезаписывается другим событием-слушателем.

Я попробовал несколько обходных решений, но оказывается, что параметры поля формы нельзя переопределить и сформировать более поздние добавленные поля не принимают новых прослушивателей событий, как только строитель готов (т. Е. Добавляется внутри прослушивателя событий).

Мне действительно нужно это решить. Я что-то упускаю? Является ли движок формы Symfony2 не способен обрабатывать двухслойные зависимости полей динамической формы?

Какие-либо предложения?

Related of "Symfony2 с двумя вложенными динамическими полями формы"

Благодаря ссылке dmnptr от его первого комментария ( http://showmethecode.es/php/symfony/symfony2-4-dependent-forms/ ), я мог бы решить проблему для моего случая. Фокус в том, чтобы привязать события ко всей форме, а не к определенным полям (и PRE_SUBMIT вместо POST_SUBMIT ). Итак, класс формы теперь выглядит так:

 <?php class ServiceeventType extends AbstractType { /** * @param FormBuilderInterface $builder * @param array $options */ public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('park', 'entity', array( 'class' => 'AppBundle:Park', 'property' => 'identifyingName', 'label' => 'Park', 'required' => true, 'invalid_message' => 'Choose a Park', 'placeholder' => 'Please choose', )) // other fields ; $addFacilityForm = function (FormInterface $form, $park_id) { // it would be easier to use a Park entity here, // but it's not trivial to get it in the PRE_SUBMIT events $form->add('facility', 'entity', array( 'class' => 'AppBundle:Facility', 'property' => 'identifyingName', 'label' => 'Facility', 'required' => true, 'invalid_message' => 'Choose a Facility', 'placeholder' => null === $park_id ? 'Please choose a Park first' : 'Please Choose', 'query_builder' => function (FacilityRepository $repository) use ($park_id) { // this does the trick to get the right options return $repository->createQueryBuilder('f') ->innerJoin('f.park', 'p') ->where('p.id = :park') ->setParameter('park', $park_id) ; } )); }; $builder->addEventListener( FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($addFacilityForm) { $park = $event->getData()->getPark(); $park_id = $park ? $park->getId() : null; $addFacilityForm($event->getForm(), $park_id); } ); $builder->addEventListener( FormEvents::PRE_SUBMIT, function (FormEvent $event) use ($addFacilityForm) { $data = $event->getData(); $park_id = array_key_exists('park', $data) ? $data['park'] : null; $addFacilityForm($event->getForm(), $park_id); } ); $addFacilityStatuscodeForm = function (FormInterface $form, $facility_id) { $form->add('facilityStatuscode', 'entity', array( 'class' => 'AppBundle:FacilityStatuscode', 'property' => 'identifyingName', 'label' => 'Statuscode', 'required' => true, 'invalid_message' => 'Choose a Statuscode', 'placeholder' => null === $facility_id ? 'Please choose a Facility first' : 'Please Chosse', 'query_builder' => function (FacilityStatuscodeRepository $repository) use ($facility_id) { // a bit more complicated, that's how this model works return $repository->createQueryBuilder('fs') ->innerJoin('fs.facilityStatuscodeType', 'fst') ->innerJoin('AppBundle:Facility', 'f', 'WITH', 'f.facilityStatuscodeType = fst.id') ->where('f.id = :facility_id') ->setParameter('facility_id', $facility_id) ; } )); }; $builder->addEventListener( FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($addFacilityStatuscodeForm) { $facility = $event->getData()->getFacility(); $facility_id = $facility ? $facility->getId() : null; $addFacilityStatuscodeForm($event->getForm(), $facility_id); } ); $builder->addEventListener( FormEvents::PRE_SUBMIT, function (FormEvent $event) use ($addFacilityStatuscodeForm) { $data = $event->getData(); $facility_id = array_key_exists('facility', $data) ? $data['facility'] : null; $addFacilityStatuscodeForm($event->getForm(), $facility_id); } ); } // more code } 

Затем AJAX-материал работает, как указано в ссылке выше