【问题标题】:How to handle forms that are used on multiple pages?如何处理在多个页面上使用的表单?
【发布时间】:2011-08-09 13:45:02
【问题描述】:

我需要在多个页面上使用一个表单:

控制器

$emailForm = $this->get('form.factory')->createNamedBuilder('form', 'email_form')
    ->add('email', 'email')
    ->add('subject', 'text')
    ->add('body', 'textarea')
    ->getForm();

$request = $this->get('request');

if ($request->getMethod() == 'POST' && $request->request->has('email_form') ) {
    $emailForm->bindRequest($request);

    if ($emailForm->isValid()) {

        // do stuff ...

        $this->get('session')->setFlash('email_sent', "Woey, mail sent successfully!");

        // Redirect on the same url to prevent double posts
        return $this->redirect($this->generateUrl($this->getRequest()->attributes->get('_route')));
    }
}

return $this->render('Bundle:Form:index.html.twig', array('email_form' => $emailForm->createView()));

模板

{% if app.session.getFlash('email_sent') %}
    <p>{{ app.session.getFlash('email_sent') }}</p>
{% endif %}

<form action="{{ path(app.request.attributes.get('_route')) }}" method="post" {{ form_enctype(email_form) }}>
    {{ form_widget(email_form) }}

    <p><input type="submit" class="submit" value="Send" /></p>
</form>

它实际上只是标准的 Symfony2 形式,几乎就像教程中的一样。

我不知道如何在不重复自己(太多)的情况下在多个页面(在多个控制器操作中)有效地使用它。到目前为止,我尝试过:

  • 将逻辑放入 Base 控制器,它是我希望拥有此表单的每个控制器的父级。这种方法有两个问题:
    • 我不知道如何正确重定向到同一页面
    • 我必须在每个操作中从父级调用方法,这不是一个真正的问题,但我想必须有一些更优雅的方式
  • 在树枝中使用embedded controllers 渲染控制器。但是,我想不通how to redirect properly

那么,这些表单的常用方法是什么?

编辑:

我正在寻找无脚本解决方案。

【问题讨论】:

标签: php symfony


【解决方案1】:

我最终在我需要的每个页面上都使用了嵌入式控制器,发布到不同的 URL 并使用引荐来源网址保存 cookie。然后我验证表单,保存带有结果的 cookie,重定向回引用者并呈现结果(错误,谢谢您的消息......)。当您处理必须考虑禁用 Javascript 的场景时,这似乎是最佳选择。对于用户使用 AJAX 发布的情况,您可以使用简单的条件轻松禁用创建冗余 cookie/flash 会话。

【讨论】:

  • 我知道它很旧,但这个问题让我困惑了好几天。不错。
【解决方案2】:

Symfony2 Forms 教程也解决了您的场景,请参阅Creating Form ClassesDocs 部分,其中“您将学习如何在独立类中构建您的表单,建议您这样做,因为您的表单变得可重用” em>(同上)。

【讨论】:

  • 是的,类是一回事,处理逻辑是另一回事。我仍然需要在每个操作方法中编写相当多的逻辑。我希望有更类似于嵌入式控制器的东西,在其中我“解耦”所有逻辑(包括渲染、验证和所有其他东西)以分离方法并将其包含在我需要的模板中。
【解决方案3】:

您应该通过 ajax 帖子提交数据。

在控制器中做你的事:p 然后在树枝模板中渲染表单,而不扩展布局。 (就像现在一样)

然后在任何视图中,您只需替换结果: $('#formDiv').html(htmlReceivedBack);

我发现用新渲染的 html 再次替换整个 html div 是最简单的;您很可能会显示成功消息或某些表单错误。

这样用户不必为了发送消息/反馈而更改页面。

【讨论】:

  • 那些禁用了 javascript 的用户呢?
  • 对于那 1% 的阿妈,您仍然可以通过渐进式增强来做到这一点。您只能通过 js 挂钩操作,而不是删除 url。如果不是 xmlhttprequest,那么您可能只需要启用布局。所以表格就在它的页面上(可以这么说)。但说真的......这是 1% - 你不想要这样的客户......他们是麻烦......
  • 希望我能对 cme​​ts 投反对票。我不了解您的客户,但我的客户不会乐于损失 1% 的销售额,因为我认为他们有麻烦。
  • 希望我能对 cme​​ts 投反对票。我不了解你的公司,但我更喜欢花时间和金钱为 99% 的客户编码,为剩下的 1% 节省 40% 的工作量。与时俱进,或落伍。
猜你喜欢
  • 1970-01-01
  • 2015-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-19
  • 2014-12-02
  • 1970-01-01
  • 2022-01-14
相关资源
最近更新 更多