我不得不对集合(Symfony表单CollectionType
)进行更改以尊重排序和实体删除,并且我正在使用preSubmit
事件侦听器按this issue suggestion进行更改}。但是,这些更改并没有让它回到控制器/持久性。
preSubmit
后的数据是正确的,并且使用$event->setData($data)
在事件中设置了数据,但在$form->getData()
我的预先提交抽象类:
abstract class AbstractEntityFormType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addEventListener(FormEvents::PRE_SUBMIT, [$this, 'onPreSubmit']);
}
/**
* @param FormEvent $event
*/
public function onPreSubmit(FormEvent $event)
{
$form = $event->getForm();
$data = $event->getData();
$document = $form->getData();
foreach ($form->all() as $field) {
/** @var FormInterface $field */
$fieldName = $field->getName();
if ($field->getConfig()->getType()->getInnerType() instanceof CollectionType) {
// .. DO ALL TRANSFORMATION
}
}
$event->setData($data);
}
}
当我在这里转储$data
时,一切都是正确的。
FormType扩展此AbstractEntityFormType
类:
class DocumentType extends AbstractEntityFormType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
* @return void
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
/** ADD THE LISTENER **/
parent::buildForm($builder, $options);
$builder->add('title', TextType::class, [
'required' => true,
'constraints' => [
new NotBlank([
'message' => '"title" is empty',
]),
],
]);
$builder->add('symptoms', CollectionType::class, [
'entry_type' => SymptomType::class,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
]);
$builder->add('tags', CollectionType::class, [
'entry_type' => TagType::class,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
]);
$builder->add('submit', SubmitType::class);
}
/**
* @param OptionsResolver $resolver
* @return void
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Document::class,
]);
}
}
我的控制器操作:
/**
* @param Request $request
* @param int|null $documentId
* @return Response
*/
public function formAction(Request $request, int $documentId = null)
{
if (!$documentId) {
$document = new Document();
} else {
try {
$document = $this->documentService->getDocument($documentId);
} catch (InvalidDocumentException $e) {
return new NotFoundResponse('Document not found');
}
}
$document = $this->setAuthor($document);
$form = $this->formFactory->create(DocumentType::class, $document);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$document = $this->documentService->createDocument($form->getData());
return new RedirectResponse($this->router->generate('ui.document.view', [
'documentId' => $document->getId()
]));
}
return $this->templating->renderResponse(
'@KBS/Document/form.html.twig', [
'form' => $form->createView(),
]
);
}
在使用服务保留文档之前转储$form->getData()
时,数据不正确 - 它不受preSubmit
的影响。我错过了什么?
仅供参考,这是使用Symfony 3.2基本组件。
更新
感谢@LBT,我有点接近但仍面临一些问题。在控制器中使用这种方法,我能够在提交表单时从请求中获取正确的数据:
public function formAction(Request $request, int $documentId = null)
{
if (!$documentId) {
$document = new Document();
} else {
try {
$document = $this->documentService->getDocument($documentId);
} catch (InvalidDocumentException $e) {
return new NotFoundResponse('Document not found');
}
}
$document = $this->setAuthor($document);
$form = $this->formFactory->create(DocumentType::class, $document);
if ($request->isMethod('POST')) {
$form->submit($request->request->get($form->getName()));
if ($form->isSubmitted() && $form->isValid()) {
$document = $this->documentService->createDocument($form->getData());
return new RedirectResponse($this->router->generate('ui.document.view', [
'documentId' => $document->getId()
]));
}
}
return $this->templating->renderResponse(
'@KBS/Document/form.html.twig', [
'form' => $form->createView(),
]
);
}
但是,$form->submit($request->request->get($form->getName()));
也会在转换之前保存不正确的(原始)数据。即使请求中的数据是正确的:
/var/www/html/src/Controller/DocumentController.php:94:
array (size=8)
'title' => string 'Tag test' (length=8)
'symptoms' =>
array (size=1)
0 =>
array (size=3)
'position' => string '0' (length=1)
'title' => string 'The smell is terrible' (length=21)
'description' => string 'pew' (length=3)
'tags' =>
array (size=4)
0 =>
array (size=1)
'title' => string 'Volvo' (length=5)
1 =>
array (size=1)
'title' => string 'Engine' (length=6)
2 =>
array (size=1)
'title' => string 'BMW' (length=3)
3 =>
array (size=1)
'title' => string 'Funky' (length=5)
感觉我越来越近了,但由于某些原因,我似乎无法将此请求数据用作suggested in the documentation。