2013-06-24 32 views
10

我想单独表单验证逻辑:Symfony的2 - 独立的形式逻辑,表演形式错误后重定向

public function contactAction() 
{ 
    $form = $this->createForm(new ContactType()); 

    $request = $this->get('request'); 
    if ($request->isMethod('POST')) { 
     $form->submit($request); 
     if ($form->isValid()) { 
      $mailer = $this->get('mailer'); 
      // .. setup a message and send it 

      return $this->redirect($this->generateUrl('_demo')); 
     } 
    } 

    return array('form' => $form->createView()); 
} 

我想转换成2个独立的动作:

public function contactAction() 
{ 
    $form = $this->createForm(new ContactType()); 
    return array('form' => $form->createView()); 
} 

public function contactSendAction() 
{ 
    $form = $this->createForm(new ContactType()); 
    $request = $this->get('request'); 
    if ($request->isMethod('POST')) { 
     $form->submit($request); 
     if ($form->isValid()) { 
      $mailer = $this->get('mailer'); 
      // .. setup a message and send it using 

      return $this->redirect($this->generateUrl('_demo')); 
     } 
    } 
    // errors found - go back 
    return $this->redirect($this->generateUrl('contact')); 
} 

的问题是,当表单中存在错误时 - 在表单验证和重定向之后,不会在contactAction中显示。 (可能它们在重定向后已经被遗忘 - 错误上下文将会丢失)

回答

6

如果您查看CRUD generator生成的代码如何处理此问题,您将看到失败的表单验证不会返回重定向,而是使用与GET方法相同的视图。所以在你的例子中你只需要:

return $this->render("YourBundle:Contact:contact.html.twig", array('form' => $form->createView())) 

而不是返回重定向。这意味着您不会像重定向一样丢失表单错误。 CRUD生成器添加的其他内容是Method requirement,这意味着您可以指定ContactSendAction需要POST方法,因此不需要额外的if($request->isMethod('POST')){语句。

你也可以返回一个数组,如果你在其他地方指定的模板,例如,你可以使用@Template annotation,然后就

return array('form' => $form->createView()) 
+0

感谢您提供有关方法要求的信息,并使用返回视图而不是重定向。但是,如果我将使用视图,它将与它一样 - 2逻辑不再分开。有什么办法可以使用重定向,不要松散的表单错误? – pleerock

+0

重定向而不是丢失表单数据似乎不是正确的想法。您可以在会话中设置错误并将它们添加到表单中,但这样做存在潜在的缺陷。你想通过逻辑分离来摆脱什么?如果你愿意,你可能'返回$ this-> contactAction();' – Luke

+0

对不起,我最后一条评论关于return $ this-> contactAction();是我吐口水,并没有很好的考虑 – Luke

2

这似乎为我的Symfony 2.8工作:

use Symfony\Component\HttpFoundation\Request; 
use Symfony\Bundle\FrameworkBundle\Controller\Controller; 

class MyController extends Controller { 
    public function templateAction() 
    { 
     $form = $this->createForm(new MyFormType(), $myBoundInstance); 

     if ($session->has('previousRequest')) { 
      $form = $this->createForm(new MyFormType()); 
      $form->handleRequest($session->get('previousRequest')); 
      $session->remove('previousRequest'); 
     } 

     return array(
      'form' => $form->createView(), 
     ); 
    } 

    public function processingAction(Request $request) 
    { 

     $form = $this->createForm(new MyFormType(), $myBoundInstance); 
     $form->handleRequest($request); 

     if ($form->isValid()) { 
      // do some stuff 
      // ... 

      return redirectToNextPage(); 
     } 

     $session->set('previousRequest', $request); 

     // handle errors 
     // ... 

     return redirectToPreviousPage(); 
    } 
} 

请注意,redirectToNextPageredirectToPreviousPage以及MyFormType是伪代码。你将不得不用你自己的逻辑来替换这些位。