У меня есть форма, встроенная в 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).
Вы можете найти объяснения и примеры в документах .