问题描述
我正在尝试使用以下功能在 Symfony 5 中管理同一页面中的多个表单,但似乎每次我尝试提交表单时,即使它不是列表中的第一个表单,也只处理列表的第一个表单已提交:
I am trying to manage multiple forms in the same page in Symfony 5 with the following function, but it seems that every time I try to submit a form, only the first form of the list is handled even if it is not the one that has been submitted:
class ContentController extends AbstractController
{
/**
* @Route("/category/edition/{content}", name="edit_category")
*/
public function edition(Request $request, Category $content): Response
{
$forms = [
"edit_category" => $this->createForm(EditCategoryType::class, $content),
"create_post" => $this->createForm(CreatePostType::class)
];
foreach($forms as $form) {
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()) {
// Always prints edit_category
// even when that is the the create_post that is submitted
return var_dump($form->getName());
}
}
return $this->render(
'content/edition.html.twig',
[
'forms' => \array_map(
function($form) {
return $form->createView();
},
$forms
),
'content' => $content,
]
);
}
}
我在其他帖子中看到表单的名称有时会引起问题,但我检查过表单确实有不同的名称,并且我还尝试调用 handleRequest()
在单独的 foreach
循环中的每个表单上,因为我在一些帖子中看到过这样做,但它(我必须说非常预期)并没有改变行为.
I have seen in other posts that the name of the forms can sometime raise an issue, but I have checked that the forms do have different names, and I have also tried to call handleRequest()
on every form in a separate foreach
loop because I have seen this done in some posts, but it (quite expectedly I must say) didn't change the behavior.
而且我似乎没有找到关于如何在 Symfony 的同一个控制器中处理多个表单的任何一致的最佳实践技巧,所以我想知道什么是最好的方法,或者是否定义更清晰为每个表单设置单独的操作路径,以完全避免此问题.
And I didn't seem to find any unanimous best practice tips about how to handle multiple forms in the same Controller in Symfony, so I was wondering what is the best way to do it, or if it would be cleaner to define a separate action route for each form in order to avoid this problem altogether.
如果需要,content/edition.html.twig
文件看起来像这样:
If needed, the content/edition.html.twig
file looks something like that:
{% set edit_category_form = forms['edit_category'] %}
{% set create_post_form = forms['create_post'] %}
{{ form_start(edit_category_form) }}
{{ form_errors(edit_category_form) }}
{{ form_end(edit_category_form) }}
{{ form_start(create_post_form) }}
{{ form_errors(create_post_form) }}
{{ form_end(create_post_form) }}
(Category
是一个经典的 Symfony 实体,EditCategoryType
是一种与 Category
实体和 CreatePostType
相关联的表单是与另一个 Symfony 实体关联的表单)
(Category
is a classical Symfony entity, EditCategoryType
is a form associated with the Category
entity and CreatePostType
is a form associated with another Symfony entity)
推荐答案
经过一些研究,似乎出于某种原因,如果(且仅当?)表单在处理请求之前构建:
After some research, it seems for some reason like it works if (and only if?) the form is build just before handling the request:
class ContentController extends AbstractController
{
/**
* @Route("/category/edition/{content}", name="edit_category")
*/
public function edition(Request $request, Category $content): Response
{
$self = $this;
$formBuilders = [
"edit_category" => function() use ($self, $content) {
return $self->createForm(EditCategoryType::class, $content);
},
"create_post" => function() use ($self, $content) {
return $self->createForm(CreatePostType::class);
},
];
$forms = [];
foreach($formBuilders as $key => $formBuilder) {
$form = $formBuilder();
$forms[$key] = $form;
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()) {
// Does print the name of the right form
return var_dump($form->getName());
}
}
return $this->render(
'content/edition.html.twig',
[
'forms' => \array_map(
function($form) {
return $form->createView();
},
$forms
),
'content' => $content,
]
);
}
}
它有效,但感觉不是处理这个问题的正确方法!
It works but it doesn't feel like a proper way to handle this !
这篇关于Symfony 5:在一个控制器中处理多个表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!