【问题标题】:How do I make my forms modular in Symfony?如何在 Symfony 中使我的表单模块化?
【发布时间】:2014-02-23 22:05:53
【问题描述】:

我在一个页面中有 10 个表单(它们位于标签页中)。

我的控制器功能非常庞大,为了使表单模块化,我打算只在我的控制器函数中显示表单,然后向其对应的控制器执行 POST。

这 10 种表单中的一些在其他页面中使用,因此通过更改操作 url,可以更轻松地在单独的控制器中管理它们。

但是,如果表单无效,我将如何显示表单错误并防止重置表单?

如果嵌入式控制器可以重定向,我可以实现这一点。我错过了另一个选择吗?

Symfony2 必须有一个不允许在嵌入式控制器中重定向的理由,但我想知道为什么。

第三次修改:

实际表格的图片:http://imgur.com/sIx3sgs,tnZkvqM,ZAP950s,hk45oTW#0

  1. 图片1:Step1(只能创建一次)
  2. 图2:Step5(可多次创建)可以看到创建表单和编辑表单
  3. 图 3:Step5 ui 表单向上滑动。
  4. 图 4:Step6 与 Step1 相同

这些表单不需要按顺序排列,用户可以创建并保存step6,而无需创建step1。

第二次修改:

这不是一个多步骤表单。为方便起见,我将它们命名为 Step1Step2 等。

编辑:

这就是我所拥有的:

class DefaultController extends Controller{
    public function processAction(){
        $request = $this->getRequest();
        /*** FORM 1 ****/
        $entity  = new Step1();
        $form1   = $this->createForm(new Step1Type(), $entity);
        if ($request->getMethod() == 'POST'){
            $form1->bindRequest($request);
            if($form1->isValid()){
                return $this->redirect($this->generateUrl('some_link'));
            }
        }
        /***/
        //Do the same for other forms

        return array(
            'form1'   => $form1->createView()
            //[...to form10]
        );
    }
}

这是我想要的:(我会用嵌入式控制器来做,但你不能重定向)

class DefaultController extends Controller{
    public function processAction(){
        $request = $this->getRequest();
        /*** FORM 1 ****/
        $entity  = new Step1();
        $form1   = $this->createForm(new Step1Type(), $entity);
        //change $form1 action url to point to Step1Controller->createAction()
        /***/
        //Do the same for other forms

        return array(
            'form1'   => $form1->createView()
            //[...to form10]
        );
    }
}
class Step1Controller extends Controller{
    public function createAction(){
        $request = $this->getRequest();

        $entity  = new Step1();
        $form   = $this->createForm(new Step1Type(), $entity);

        $form->bindRequest($request);
        if($form->isValid()){
            //save entity
            return $this->redirect($this->generateUrl($getRedirectLinkFromForm));
        }
        return $this->redirect($this->generateUrl('some_other_link')); 
    }
}

【问题讨论】:

  • @AndrzejOśmiałowski 我发布了我的代码。我对其进行了编辑以使其更短。
  • 您的表单(整个表单)是step kind 的表单吗?
  • @AndrzejOśmiałowski 不,他们被命名为step,但他们来自完全不同的实体。我无法将其设为多步骤表单,因为某些步骤是重复的(用户可以创建 step 实体的多个实例)。
  • 我换个方式问:每个表单的职责是什么?
  • @AndrzejOśmiałowski 创建/编辑实体,然后将其应用于数据库。对于某些实体,我必须调用额外的方法,例如$step1->setSomething($getSomething),它是最小的,但是当你将这些最小调用乘以 10 时,你最终会得到一个大函数。另外,如果我需要使用完全相同的表单,那么我希望能够创建表单并让对应的控制器处理帖子。

标签: php forms symfony


【解决方案1】:

我想出了 4 个我能想到的解决方案,按照从最好到最坏的顺序排列:

  1. AJAX
  2. 嵌入式控制器中没有重定向
  3. 保存在会话中发布的数据/表单错误,以防表单无效
  4. 修改 Symfony2 内部以允许从嵌入式控制器重定向

AJAX

这实际上是最好的,因为它减少了整个页面的请求并且高度模块化。

您将渲染所有 10 个嵌入式控制器,但每个提交按钮将改为执行指向对应控制器的 ajax 发布,该控制器将只处理对应的表单,并且只会返回该特定表单的视图。

而且您不需要花哨的 javascript,因为您只需要在单击提交时进行 AJAX 调用并将响应加载到表单所在的 div。


嵌入式控制器中没有重定向

这样做的问题是,如果用户按 F5,它会重新发送 POST 数据。


保存在会话中发布的数据/表单错误以防表单无效

修改 Symfony2 内部以允许来自嵌入式控制器的重定向

这两个选项不太理想,因为它会产生复杂性。

【讨论】:

  • 我仍然认为这可能是一个设计问题 ;) AJAX 解决方案看起来不错,因为它允许您使用表单事件,这在许多情况下可能会有所帮助。
猜你喜欢
  • 1970-01-01
  • 2014-05-23
  • 2021-11-07
  • 1970-01-01
  • 2016-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-10
相关资源
最近更新 更多