【问题标题】:how to split long symfony form in multiple pages?如何在多个页面中拆分长的 symfony 表单?
【发布时间】:2014-02-10 20:19:06
【问题描述】:

我想为具有许多属性的实体创建一个表单。为了确保数据输入的方便性,我想将该表单拆分为多个页面(例如 2 或 3 页)。 我们以广告实体为例:

  1. 在第 1 页,用户将输入广告文字
  2. 在第 2 页,用户将输入他的联系人
  3. 在第 3 页中,用户将提供广告的 (X,Y) 位置

此拆分需要在移动到下一页之前将可用数据(插入数据库中)保存在第一页中。不幸的是,由于限制,这是不可能的。

问题是:是否有任何文档或示例可以解决此问题?

如果没有可用的文档,您认为最好将我的实体拆分为 n 个实体以便每页有一个实体?

感谢您的帮助。

【问题讨论】:

    标签: symfony symfony-forms submit-button


    【解决方案1】:

    您可能应该使用CraueFormFlowBundle。它为构建多步骤表单提供了便利。

    您可以为整个流程创建一种表单类型,或为每个步骤创建一种表单类型。

    设置非常简单。一切都解释了here

    【讨论】:

    • 非常感谢。似乎是一个很好的解决方案! :)
    • 绝对完美!再次感谢!
    • 我怀疑 Bundle 是否是一个很好的解决方案。个人通常更喜欢编码作为一个很好的解决方案。
    • 不是很好的解决方案,映射仍然存在问题 => 错误字段
    • @Pmpr 第三方库如果维护良好且体面,则非常棒。当其他人已经完成并经历了琐碎的事情时,为什么还要花费数小时/天+编写自己的内部代码?只需在您自己的代码库中使用实现 3rd 方库的服务类。然后在你的代码中注入你自己的类,这样就可以很容易地将一个库换成另一个(或者你自己的,如果以后需要的话)
    【解决方案2】:

    您不必拆分您的实体,但您的表单:创建 3 个表单,每个表单都包含广告实体所需的属性。

    你需要:

    • 在控制器内的每一步都保留(而不是刷新)$ad 对象
    • 在控制器内部转发时将 $ad 对象作为参数传递
    • 在最后一步刷新 $ad 对象

    在伪代码中,您的控制器应该如下所示:

    public function newAdStep1() {
        new Ad() // New instance of $ad
        new formStep1($ad) // The first form containing only the ad text field
    
        // The form was filled, manage it...
        form->isValid()? {
            persist($ad); // Persist the first part of your ad object
            forward(newAdStep2, $ad) // Go on to step 2, your $ad object as an argument
        }
    
        // ... or display step1 to user
        createView createAdStep1.html.twig('form' => $form);
    }
    
    public function newAdStep2($ad) {
        new formStep2($ad); // Now the second form, containing the "contact" fields
        isValid ? {
            persist($ad)
            forward(newAdStep3, $ad)
        }
        createView createAdStep2($form, $ad); // Your $ad object needs to be sent to the view
    }
    
    public function newAdStep3($ad) {
        new formStep3($ad); // Third and last form, containing the (X,Y) fields
        isValid ? {
            $em->persist($ad);
            $em->flush(); // Your instance of $ad can be stored in database now
            return('success !');
        }
        return view createAdStep3($form, $ad);
    }
    

    【讨论】:

    • 非常感谢。我必须尝试你的解决方案。我有点担心 isValid()。
    • 我试过了,在createForm之后isValid返回true,所以这个方案可能不可行。然而,使用 forwards 的概念非常棒。
    • 如果你修改你的代码 sn-p 并用真实世界的代码替换它可能会有所帮助
    • 你能测试你的代码吗?我用 Symfony3 尝试了你的解决方案,但在最后一步中刷新不起作用。你能帮我吗:stackoverflow.com/questions/47650477/…
    • 如果在第一步用户关闭浏览器之后呢?
    【解决方案3】:

    您可以将所有提交的数据存储在会话或临时表中,然后在最后将它们全部保存在一起。不过,我会尽量避免这样的额外工作。

    我认为您的表单步骤很可能遵循约束规定的顺序。

    话虽如此,有时我认为这种问题可以通过做出更好的设计或工艺决策来解决。即限制问题的数量或一开始只问重要的问题。不知道来龙去脉,很难知道这是否可以做到。

    【讨论】:

    • Session不是个好地方,会导致session滥用。我会使用缓存。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-02
    • 2020-02-28
    • 1970-01-01
    • 1970-01-01
    • 2012-06-28
    相关资源
    最近更新 更多