У меня есть большая форма с полями времени, даты, выбора и EntityType. Форма не связана с сущностью, но она содержит поля из других объектов. Другими словами, у меня нет data_class
в OptionsResolver формы FormType.Symfony формы резервного копирования состояния базы данных и восстановления/или: как предварительно заполнить форму из базы данных
Вот мой formtype: (показывая только одно поле для простоты)
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('company', EntityType::class, array(
'placeholder' => 'Companies',
'class' => 'AppBundle:Company',
'choice_label' => 'name',
'multiple' => true,
'query_builder' => function (EntityRepository $repository) {
return $repository->createQueryBuilder('c')->orderBy('c.name', 'ASC');
},
'required' => false
))
//... much more fields
}
public function configureOptions(OptionsResolver $resolver)
{
// This form is not linked to an Entity
// Therefore no `data_class`
}
В контроллере я могу создавать резервные копии данных формы. Вызывается FormState. Я сохраняю FormState в базе данных следующим образом:
namespace AppBundle\Controller;
class ReportController extends Controller
{
/** // ... */
public function listAction(Request $request)
{
$form = $this->createForm(ReportType::class);
$form->handleRequest($request);
// Save the form to a FormState
if ($form->isSubmitted() && $form->getClickedButton()->getName() == 'saveFormState') {
$formStateManager = $this->get('app.manager.form_state');
// Get form data that we want to save
$data = $form->getData();
$name = 'Stackoverflow example'; // give it a name
$formState = $formStateManager->createNewFormState(); // Create new FormState Entity object
$formState->setName($name);
$formState->setData($data);
$formStateManager->save($formState);
}
// ...
}
}
Все это выше работает отлично. Но теперь эта сложная часть, я должен вернуть backupdata в форму. Пользователь может выбрать предыдущее состояние формы из списка FormStates. Затем нажмите кнопку загрузки.
Атрибут объекта FormState, который я пытаюсь загрузить в форму, является просто результатом $form->getData()
. Таким образом, обычный массив без объектов. Возможно, это проблема, но я не могу заставить ее работать.
Этот массив data
- это то, что я пытаюсь загрузить в форму, чтобы он переместил свои значения. Я попробовал это через $form->setData()
, или создав новую форму с $this->createForm(ReportType::class, $data)
. Оба отказались с тем же сообщением об ошибке: Entities passed to the choice field must be managed. Maybe persist them in the entity manager?
.
Я попробовал два способа добавления данных:
Первая попытка, в контроллере:
namespace AppBundle\Controller;
class ReportController extends Controller
{
/** // ... */
public function listAction(Request $request)
{
if ($form->isSubmitted() && $form->getClickedButton()->getName() == 'loadFormState') {
// ...
$form = $this->createForm(ReportType::class, $formState->getData()); // <-- throws the error
$form->submit($formState->getData());
}
}
}
Вторая попытка, с помощью FormEvent абонента: Когда я это делаю через абонента FormEvent, как показано ниже, я получаю ту же ошибку. Вот мой код:
namespace AppBundle\Form\EventListener;
class ReportFieldsSubscriber implements EventSubscriberInterface
{
// ...
public static function getSubscribedEvents()
{
return array(
FormEvents::PRE_SUBMIT => array(
array('loadFormState'),
),
);
}
/**
* Load selected FormState in form
* @param FormEvent $event
*/
public function loadFormState(FormEvent $event)
{
$form = $event->getForm();
//...
// Choosen FormState
$formState = $formStateManager->findOneById($formStateId);
$formStateData = $formState->getData();
$form->setData($formStateData); // <-- Set data, trows error
// ...
}
}
Как я сказал, что оба решения бросает ошибку: Entities passed to the choice field must be managed. Maybe persist them in the entity manager?
Что является предпочтительным решением в этом случае? Я могу создать фиктивный Entity и исправить эту проблему, но он чувствует себя немного уродливым, а не тем, как идти.