2013-06-24 63 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是僞代碼。你將不得不用你自己的邏輯來替換這些位。