Javascript 创建 POST,Symfony 控制器处理它并重定向,但新页面未显示
Javascript creates the POST, the Symfony controller handles it and redirects, but the new page is not shown
我是 Symfony 的初学者,PHP 和 Javascript。我正在为基于 Fancytree 的 Javascript 树形而苦苦挣扎。多亏了论坛,我完成了所有工作,将表单数据回发到控制器,处理请求并重定向到成功页面。问题是成功页面从不显示。 IE 和 Firefox 调试器都不显示错误。我不再进步了,我被困住了。
这是我的控制器:
namespace Solar\DataBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Config\Definition\Exception\Exception;
class DefaultController extends Controller
{
/**
* Test data sent to Twig and javascript tree
*
* @Route("/form_tree_demo", name="form_tree_demo")
* @Method({"GET", "POST"})
*/
public function formTreeDemoAction(Request $request)
{
$test = 'Test string';
$testArray =
array(
array(
'name'=> '1',
'title' => '1',
'children' =>
array(
array('name' => '1.1',
'title' => '1.1'
),
array('name' => '1.2',
'title' => '1.2'
)
)
),
array(
'name'=> '2',
'title' => '2',
'children' =>
array(
array('name' => '2.1',
'title' => '2.1'
),
array('name' => '2.2',
'title' => '2.2'
)
)
)
);
$form = $this->createFormBuilder()
->add('save', SubmitType::class, array('label' => 'Post to the controller'))
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
//for debug
//throw new Exception(var_dump($form->getData()));
return $this->redirectToRoute('success', array('message' => 'Post handled'));
}
return $this->render('formtreedemo.html.twig',
array(
'tree_form' => $form->createView(),
'test_array' => json_encode($testArray)
)
);
}
/**
* @Route("/success", name="success")
*/
public function successAction()
{
return $this->render('success.html.twig');
}
}
这是 Twig 形式:
{% extends 'base.html.twig' %}
{% block body %}
<h1>A demo form with Fancytree</h1>
{{ form_start(tree_form) }}
<div id="tree" name="selNodes">
</div>
Additional data: <input type="text" name="otherFormData" /><br><br>
{{ form_end(tree_form) }}
{% endblock %}
{% block javascripts %}
<script type="text/javascript" src="{{asset('assets/vendor/jquery/dist/jquery.js')}}"></script>
<script type="text/javascript" src="{{asset('assets/vendor/jquery-ui/jquery-ui.js')}}"></script>
<script type="text/javascript" src="{{asset('assets/vendor/bootstrap/dist/js/bootstrap.js')}}"></script>
<link rel="stylesheet" type="text/css" id="skinSheet" href="{{asset('assets/vendor/fancytree/src/skin-lion/ui.fancytree.css')}}" />
<script type="text/javascript" src="{{asset('assets/vendor/fancytree/src/jquery.fancytree.js')}}"></script>
<script type="text/javascript">
$(function(){
$("#tree").fancytree({
checkbox: true,
selectMode: 2,
source:$.parseJSON('{{test_array}}'.replace(/"/ig,'"'))
});
$("form").submit(function() {
$("#tree").fancytree("getTree").generateFormElements();
jQuery.ajax({
type: "POST",
url: "{{path("form_tree_demo")}}",
data: formData
});
return false;
});
});
</script>
{% endblock %}
最后是 IE 控制台转储:
URL Method Result Type Initiateur
/web/app_dev.php/form_tree_demo GET 200 text/html actualiser
/web/assets/vendor/bootstrap/dist/css/bootstrap.css GET 200 text/css <link rel="stylesheet">
/web/assets/vendor/bootstrap/dist/css/bootstrap-theme.css GET 200 text/css <link rel="stylesheet">
/web/assets/vendor/jquery/dist/jquery.js GET 200 application/javascript <script>
/web/assets/vendor/jquery-ui/jquery-ui.js GET 200 application/javascript <script>
/web/assets/vendor/bootstrap/dist/js/bootstrap.js GET 200 application/javascript <script>
/web/assets/vendor/fancytree/src/skin-lion/ui.fancytree.css GET 200 text/css <link rel="stylesheet">
/web/assets/vendor/fancytree/src/jquery.fancytree.js GET 200 application/javascript <script>
/web/app_dev.php/_wdt/115370 GET 200 text/html XMLHttpRequest
/web/assets/vendor/fancytree/src/skin-lion/icons.gif GET 200 image/gif background-image
/web/app_dev.php/form_tree_demo POST 302 text/html XMLHttpRequest
/web/app_dev.php/success?message=Post%20handled GET 200 text/html XMLHttpRequest
补充信息:
我 运行 Symfony 3.2 在 Windows 8、OpenSuse 和 Ubuntu VM 服务器下。到处都是同样的结果。已弃用的 Dynatree 的结果也相同。
将不胜感激。
让-米歇尔
您需要处理 ajax 的 success/failure 并从那里加载新页面。目前,您正在 returning 控制器中重定向调用的 html,并且您的 javascript 函数不以任何方式处理 return,只是 return是假的。
如果您的控制器中的表单仅响应 ajax,则在成功时传回 url 以重定向到,然后让您的 javascript 执行重定向。
如果表单仅用于处理 ajax 调用,我个人会创建一个 route/function 来处理该调用。
这就是为什么您可以执行一些检查(如 $request->isXmlHttpRequest()
)以确保调用仅来自 ajax。
例如
public function ajaxAction(Request $request)
{
if ($request->isXmlHttpRequest()) {
$form_element1 = $request->request->get('form_element1');
$form_element2 = $request->request->get('form_element2');
// do whatever
$data['success'] = true;
$data['url'] = $this->generateUrl('new_route');;
return new \Symfony\Component\HttpFoundation\JsonResponse($data);
}
}
那么你的javascript
<script type="text/javascript">
$(function(){
$("#tree").fancytree({
checkbox: true,
selectMode: 2,
source:$.parseJSON('{{test_array}}'.replace(/"/ig,'"'))
});
$("form").submit(function(e) {
e.preventDefault();
var formData = $("#tree").fancytree("getTree").generateFormElements();
var jqxhr = $.ajax({
type: "POST",
url: "{{path('ajax_action')}}",
data: formData
})
.done(function(data) {
if (data.success === true) {
window.location.href = data.url;
}
})
.fail(function(data) {
alert('error');
})
.always(function(data) {
});
return false;
});
});
</script>
我是 Symfony 的初学者,PHP 和 Javascript。我正在为基于 Fancytree 的 Javascript 树形而苦苦挣扎。多亏了论坛,我完成了所有工作,将表单数据回发到控制器,处理请求并重定向到成功页面。问题是成功页面从不显示。 IE 和 Firefox 调试器都不显示错误。我不再进步了,我被困住了。
这是我的控制器:
namespace Solar\DataBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Config\Definition\Exception\Exception;
class DefaultController extends Controller
{
/**
* Test data sent to Twig and javascript tree
*
* @Route("/form_tree_demo", name="form_tree_demo")
* @Method({"GET", "POST"})
*/
public function formTreeDemoAction(Request $request)
{
$test = 'Test string';
$testArray =
array(
array(
'name'=> '1',
'title' => '1',
'children' =>
array(
array('name' => '1.1',
'title' => '1.1'
),
array('name' => '1.2',
'title' => '1.2'
)
)
),
array(
'name'=> '2',
'title' => '2',
'children' =>
array(
array('name' => '2.1',
'title' => '2.1'
),
array('name' => '2.2',
'title' => '2.2'
)
)
)
);
$form = $this->createFormBuilder()
->add('save', SubmitType::class, array('label' => 'Post to the controller'))
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
//for debug
//throw new Exception(var_dump($form->getData()));
return $this->redirectToRoute('success', array('message' => 'Post handled'));
}
return $this->render('formtreedemo.html.twig',
array(
'tree_form' => $form->createView(),
'test_array' => json_encode($testArray)
)
);
}
/**
* @Route("/success", name="success")
*/
public function successAction()
{
return $this->render('success.html.twig');
}
}
这是 Twig 形式:
{% extends 'base.html.twig' %}
{% block body %}
<h1>A demo form with Fancytree</h1>
{{ form_start(tree_form) }}
<div id="tree" name="selNodes">
</div>
Additional data: <input type="text" name="otherFormData" /><br><br>
{{ form_end(tree_form) }}
{% endblock %}
{% block javascripts %}
<script type="text/javascript" src="{{asset('assets/vendor/jquery/dist/jquery.js')}}"></script>
<script type="text/javascript" src="{{asset('assets/vendor/jquery-ui/jquery-ui.js')}}"></script>
<script type="text/javascript" src="{{asset('assets/vendor/bootstrap/dist/js/bootstrap.js')}}"></script>
<link rel="stylesheet" type="text/css" id="skinSheet" href="{{asset('assets/vendor/fancytree/src/skin-lion/ui.fancytree.css')}}" />
<script type="text/javascript" src="{{asset('assets/vendor/fancytree/src/jquery.fancytree.js')}}"></script>
<script type="text/javascript">
$(function(){
$("#tree").fancytree({
checkbox: true,
selectMode: 2,
source:$.parseJSON('{{test_array}}'.replace(/"/ig,'"'))
});
$("form").submit(function() {
$("#tree").fancytree("getTree").generateFormElements();
jQuery.ajax({
type: "POST",
url: "{{path("form_tree_demo")}}",
data: formData
});
return false;
});
});
</script>
{% endblock %}
最后是 IE 控制台转储:
URL Method Result Type Initiateur
/web/app_dev.php/form_tree_demo GET 200 text/html actualiser
/web/assets/vendor/bootstrap/dist/css/bootstrap.css GET 200 text/css <link rel="stylesheet">
/web/assets/vendor/bootstrap/dist/css/bootstrap-theme.css GET 200 text/css <link rel="stylesheet">
/web/assets/vendor/jquery/dist/jquery.js GET 200 application/javascript <script>
/web/assets/vendor/jquery-ui/jquery-ui.js GET 200 application/javascript <script>
/web/assets/vendor/bootstrap/dist/js/bootstrap.js GET 200 application/javascript <script>
/web/assets/vendor/fancytree/src/skin-lion/ui.fancytree.css GET 200 text/css <link rel="stylesheet">
/web/assets/vendor/fancytree/src/jquery.fancytree.js GET 200 application/javascript <script>
/web/app_dev.php/_wdt/115370 GET 200 text/html XMLHttpRequest
/web/assets/vendor/fancytree/src/skin-lion/icons.gif GET 200 image/gif background-image
/web/app_dev.php/form_tree_demo POST 302 text/html XMLHttpRequest
/web/app_dev.php/success?message=Post%20handled GET 200 text/html XMLHttpRequest
补充信息: 我 运行 Symfony 3.2 在 Windows 8、OpenSuse 和 Ubuntu VM 服务器下。到处都是同样的结果。已弃用的 Dynatree 的结果也相同。
将不胜感激。
让-米歇尔
您需要处理 ajax 的 success/failure 并从那里加载新页面。目前,您正在 returning 控制器中重定向调用的 html,并且您的 javascript 函数不以任何方式处理 return,只是 return是假的。
如果您的控制器中的表单仅响应 ajax,则在成功时传回 url 以重定向到,然后让您的 javascript 执行重定向。
如果表单仅用于处理 ajax 调用,我个人会创建一个 route/function 来处理该调用。
这就是为什么您可以执行一些检查(如 $request->isXmlHttpRequest()
)以确保调用仅来自 ajax。
例如
public function ajaxAction(Request $request)
{
if ($request->isXmlHttpRequest()) {
$form_element1 = $request->request->get('form_element1');
$form_element2 = $request->request->get('form_element2');
// do whatever
$data['success'] = true;
$data['url'] = $this->generateUrl('new_route');;
return new \Symfony\Component\HttpFoundation\JsonResponse($data);
}
}
那么你的javascript
<script type="text/javascript">
$(function(){
$("#tree").fancytree({
checkbox: true,
selectMode: 2,
source:$.parseJSON('{{test_array}}'.replace(/"/ig,'"'))
});
$("form").submit(function(e) {
e.preventDefault();
var formData = $("#tree").fancytree("getTree").generateFormElements();
var jqxhr = $.ajax({
type: "POST",
url: "{{path('ajax_action')}}",
data: formData
})
.done(function(data) {
if (data.success === true) {
window.location.href = data.url;
}
})
.fail(function(data) {
alert('error');
})
.always(function(data) {
});
return false;
});
});
</script>