Intereting Posts

Symfony2 – Как остановить Form-> handleRequest от обнуления полей, которые не существуют в данных post

У меня есть форма, встроенная в Symfony, и при визуализации в представлении форма html может содержать или не содержать все поля в объекте формы (у сущности есть несколько разных состояний, а не все поля распределены в вид).

Проблема заключается в том, что когда форма обрабатывается обработчиком отправки, методом handleRequest () объекта формы, он сбрасывает любые свойства в сущности, которые не присутствуют в данных сообщения, до нуля, сдувая любое существующее значение.

Есть ли способ сказать Symfony не быть таким глупым и обрабатывать только поля, присутствующие в данных POST?

Или я должен клонировать объект перед вызовом handleRequest, а затем перебирать значения POST и копировать связанные значения из объекта post-handleRequest в клон pre-handleRequest объекта, поэтому я сохраняю поля, которые не находятся в данные POST.

уф! как вы можете видеть, это немного глупое решение, немного неприятная проблема, tbh.

Я мог бы понять, что symfony делает это, если сущность фактически являлась новым созданным объектом, но она была загружена из БД, а затем вызвана handleRequest – она ​​должна быть достаточно разумной, чтобы знать, что объект уже инициализирован, и только установите поля, переданные в Данные POST.

Спасибо за любую помощь.

С уважением

Стив.

Короче говоря, не используйте handleRequest .

Вы должны использовать submit напрямую, а параметр clearMissing – false.

Symfony / Компонент / Форма / FormInterface

 /** * Submits data to the form, transforms and validates it. * * @param null|string|array $submittedData The submitted data. * @param bool $clearMissing Whether to set fields to NULL * when they are missing in the * submitted data. * * @return FormInterface The form instance * * @throws Exception\AlreadySubmittedException If the form has already been submitted. */ public function submit($submittedData, $clearMissing = true); 

Когда вы используете handleRequest он handleRequest , какие данные вы хотите отправить, а затем отправляет их, используя $form->submit($data, 'PATCH' !== $method); , что означает, что, если вы не отправили форму с использованием метода PATCH он очистит поля.

Чтобы отправить форму самостоятельно без очистки, вы можете использовать …

 $form->submit($request->get($form->getName()), false); 

.. которые получают массив данных формы из запроса и отправляют его напрямую, но с параметром clear missing fields установлено значение false.

Если ваше лицо имеет разные состояния, вы можете отразить это в своем типе формы.

Либо создайте несколько типов форм (возможно, используя наследование), содержащие различные настройки полей, и создайте требуемый экземпляр в своем контроллере.

Что-то вроде этого:

 class YourState1FormType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('someField') ; } } class YourState2FormType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('someOtherField') ; } } 

Или передать параметр в один тип формы при создании в контроллере и адаптировать настройку поля в зависимости от состояния. Если вы не добавляете поля, которые не присутствуют, они не обрабатываются.

Что-то вроде этого:

 class YourFormType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { if($options['state'] == 'state1') { $builder ->add('someField') ; } else if($options['state'] == 'state2') { $builder ->add('someOtherField') ; } } public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults(array( 'state' => 'state1' )); } } 

Обновить

Другой подход, который вы можете предпринять для изменения формы на основе представленных данных, – зарегистрировать прослушиватели событий в событиях PRE_SET_DATA и POST_SUBMIT формы. Эти слушатели вызывают в разные моменты процесса подачи формы и позволяют изменять форму в зависимости от объекта данных, переданного типу формы при создании формы (PRE_SET_DATA) или данных формы, представленных пользователем (POST_SUBMIT).

Вы можете найти объяснения и примеры в документах .