【问题标题】:Merge 2 actions from 2 different controllers in one view - Symfony2在一个视图中合并来自 2 个不同控制器的 2 个动作 - Symfony2
【发布时间】:2015-04-16 23:13:57
【问题描述】:

我有一个 Symfony2 网站的当前情况:

  • loginActionSecurityController 中执行的登录功能。当访问其路线时,该操作在渲染视图时使用参数(p1、p2、p3)。 (same as FOSUserBundle)

  • RegistrationController 中的注册功能 registerAction 正在返回使用其他参数 p3、p4、p5 的视图。 (same as FOSUserBundle)

参数用于在表单无效时保存错误消息。

我需要显示一个同时显示两种功能(登录表单和注册表单)的主页,但它也可以处理由于无效数据引起的错误。

我可以成功显示首页了(MembersManagementBundle::index.html.twig):

{{ render(controller('MembersManagementBundle:Security:login')) }}

{{ render(controller('MembersManagementBundle:Registration:register')) }}

控制器:

class IndexController extends Controller
{

     public function indexAction()
    {
        return $this->render('MembersManagementBundle::index.html.twig');
    }
}

如果输入了正确的值(无论是登录还是注册表),表单提交后重定向到正确的目标页面。

但是,

如果向其中一个表单输入了错误数据,则会重定向到其特定视图并出现特定错误(这是正常的,因为提交表单会调用action属性中指定的url,该属性会调用相应控制器中的相应操作)。

问题:

是否可以在一个模板中包含所有参数的总和的两个操作?我应该开发indexAction 以便它包含两个动作的逻辑吗?或者还有另一种方法可以将两个动作分开但将结果合并到 indexAction 中? 最后我的目标是能够生成带有所需错误的索引页面(p1,p2,p3p4,p5,p6)。

谢谢。非常感谢您的帮助。

【问题讨论】:

  • 能否请您提供登录和注册操作的逻辑?
  • @KhorneHoly。感谢您的反馈,请查看我在编辑中提供的链接(来自 FOSUserBundle github)
  • 你的动作最后是否也包含这个渲染? return $this->render('FOSUserBundle:Registration:register.html.twig', array( 'form' => $form->createView(), )); 如果是,则需要将渲染操作编辑到索引!
  • @KhorneHoly,我这样做会不会陷入无限循环(渲染嵌套索引页面)?
  • 否,因为只有在提交表单时才会调用您的操作。所以它会是这样 -> 用户转到索引 -> 索引呈现 2 个表单 -> 2 个表单中的 1 个将被提交 -> 动作将被触发 -> 动作呈现索引 -> 索引将呈现两个控制器它给出了表格,但由于表格不会自动提交,因此不可能有无限循环。您必须考虑的唯一想法是表单操作在第二次调用中记住第一次调用中的错误的方式。希望这有点可以理解。

标签: php symfony model-view-controller controller fosuserbundle


【解决方案1】:

这是您现在的流程:

  1. 用户转到索引页面。
  2. 索引页包括 2 个表单,因为在 twig 中调用了渲染函数。
  3. 用户提交两种表单之一。
  4. 表单提交并运行表单背后的操作。
  5. 表单仅呈现树枝模板,因为这就是动作最终所做的。

现在您需要将其编辑为以下内容:

  1. 1-4 是一样的。
  2. 表单再次呈现索引控制器,这将再次呈现 2 个表单。不能有无限循环,因为不会从程序逻辑再次提交表单。
  3. 现在还剩下一点:由于表单将执行 2 次操作,错误将如何显示?因为它们将在第一次运行时设置,而不是在第二次运行。

你是怎么做的:

你在 loginAction 中添加一个变量:

$loginErrorsArray = array();

无论您将错误添加到表单的何处,都将其添加到数组中。

//instead of $form->addError(...);
$loginErrorsArray['formField'] = $errorMessage;

在渲染表单之前,您将其保存到会话中。

$this->get('session')->set('loginErrors', $loginErrorsArray);

现在,在代码开头的相同操作中,您将获取会话变量并运行它,为每个条目创建 formErrors。之后,您在会话中保存一个空数组。

$loginErrorsArray = $this->get('session')->get('loginErrors');
foreach($loginErrorsArray as $error){
    $form->addError(...);
}
$this->get('session')->set('loginErrors', array());

现在这将在动作中执行以下操作:

  1. 它获取包含错误的数组。
  2. 为发现的每个错误创建错误。 (因为在第一次运行中没有设置错误,所以不会创建)。
  3. 然后它将找到的所有错误添加到数组中。
  4. 在第二次运行中,它会将数组中的所有错误添加到表单中,但不会为数组创建任何新错误。

希望这会有所帮助。

【讨论】:

  • 感谢您的帮助,非常感谢您花时间回答这个问题。我正在阅读它,在完全理解后我会来提供反馈。再次感谢
  • 不,先生。当我更改loginActionregisterAction 以使它们呈现index.html.twig 时,会出现无限循环(在提交任何表单之前的第一次运行时)。如果我错了,希望你纠正我。对于关于错误处理的第二部分,我明白你的意思,我将使用该方法,但在解决主要问题之后。再次感谢
  • 你相信吗?无论如何,为了分享的目的,请尝试阅读这篇文章,它让我对这些问题有更多的见解:stackoverflow.com/questions/26959973/…。祝你天天快乐,谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-28
  • 1970-01-01
相关资源
最近更新 更多