在一个控制器中处理多个表单

在一个控制器中处理多个表单

本文介绍了Symfony 5:在一个控制器中处理多个表单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用以下功能在 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:在一个控制器中处理多个表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-06 01:01