当表单提交失败时,同样的表单会显示错误信息给用户,但是当他们按下F5或使用浏览器的后退/前进按钮时,会出现"确认重新提交"的弹出框。如何防止这种行为?
注意:我曾经在CodeIgniter中使用重定向方法而不会丢失错误消息,但我不知道如何处理Symfony中的相同类型的过程,因为我是新手。任何解决方案都是可以接受的。
控制器:
namespace Se'HirBundle'Controller;
use Symfony'Bundle'FrameworkBundle'Controller'Controller;
use Se'HirBundle'Entity'Task;
use Se'HirBundle'Form'Type'TaskType;
use Symfony'Component'HttpFoundation'Request;
use Symfony'Component'HttpFoundation'Response;
class TodoController extends Controller
{
public function indexAction()
{
$task = new Task();
$form = $this->createForm(new TaskType(), $task, array('action' => $this->generateUrl('todo_new')));
return $this->render('SeHirBundle:Default:todo.html.twig',
array('page' => 'Todo', 'form' => $form->createView()));
}
public function newAction(Request $request)
{
if ($request->getMethod() == 'POST')
{
$task = new Task();
$form = $this->createForm(new TaskType(), $task, array('action' => $this->generateUrl('todo_new')));
$form->handleRequest($request);
if ($form->isValid())
{
$task = $form->get('task')->getData();
$due = $form->get('due')->getData();
$data = $form->getData();
echo '<pre>'; print_r($data);
return new Response("Well done: $task - $due");
}
else
{
return $this->render('SeHirBundle:Default:todo.html.twig',
array('page' => 'Todo', 'form' => $form->createView()));
}
}
else
{
return new Response('Only POST method accepted');
}
}
}
错误冒泡true是将所有错误组合在一起的。
错误弹出是基于你的浏览器。我不确定Symfony能关闭这种功能。
required => false
早该这么做了
技巧是将表单数据保存在会话中,并使用存储在同一会话中的数据填充表单类型,以防止表单提交失败。数据一直保存在会话中,直到成功提交表单。
完整的例子在这里:防止symfony应用程序中的"Confirm form resubmission"对话框
/**
* @Route("/interest", service="my_test_bundle.controller.interest")
*/
class InterestController
{
private $formFactory;
private $router;
public function __construct(
FormFactoryInterface $formFactory,
RouterInterface $router
) {
$this->formFactory = $formFactory;
$this->router = $router;
}
/**
* @Method({"GET"})
* @Route("", name="interest_index")
* @Template()
*
* @param Request $request
*
* @return array
*/
public function indexAction(Request $request)
{
$form = $this->createForm();
$session = $request->getSession();
if ($session->has($this->getFormName())) {
$request->request->set(
$this->getFormName(),
unserialize($session->get($this->getFormName()))
);
$request->setMethod('POST');
$form->handleRequest($request);
}
return ['interest_form' => $form->createView()];
}
/**
* @Method({"POST"})
* @Route("", name="interest_create")
*
* @param Request $request
*
* @return RedirectResponse
*/
public function createAction(Request $request)
{
$session = $request->getSession();
$form = $this->createForm();
$form->handleRequest($request);
if ($form->isValid()) {
// Do something with: $form->getData();
$session->remove($this->getFormName());
$routeName = 'home_or_success_route';
} else {
$session->set(
$this->getFormName(),
serialize($request->request->get($this->getFormName()))
);
$routeName = 'interest_index';
}
return new RedirectResponse($this->router->generate($routeName));
}
private function createForm()
{
return $this->formFactory->create(
InterestType::class,
new Interest(),
[
'method' => 'POST',
'action' => $this->router->generate('interest_create'),
'attr' => ['id' => $this->getFormName()],
]
);
}
private function getFormName()
{
return InterestType::NAME;
}
}