编辑 -
我已在下面发布了答案。
问题是,当按下提交按钮时,我不明白ZF2如何/在哪里发布表单数据。那么,当我做if ($this->getRequest()->isPost()){
时
在下面的ajax调用之后,它告诉我没有发布任何数据。
当我执行上面的isPost()
if语句时,当我点击提交按钮时,它会完美地工作,告诉我数据已经发布并随后告诉我表单数据
是有效的。
这是ajax调用 -
<script>
$.ajax({
url: urlform,
type: 'POST',
dataType: 'json',
contentType: "application/json; charset=utf-8",
async: true,
data: ($("#newThoughtForm").serialize() + '&submit=go'),
success: function () {
console.log('SUBMIT WORKS');
setTimeout(function () { <?php echo $this->invokeIndexAction()->test(); ?> ;
}, 1000);
},
//This keeps getting executed because there is no response, as the controller action is not run on a Post()
error: function () {
console.log('There is error while submit');
setTimeout(function () { <?php echo $this->invokeIndexAction()->test(); ?> ;
}, 1000);
}
//I assume the data won't get pushed to the server if there is no response,
//but I can't figure out how to give a response in ZF2 since the controller is not
//run when the Post() is made.
});
这是表格 -
use Zend\Form\Form;
class newAlbumForm extends Form
{
public function __construct()
{
parent::__construct('newAlbumForm');
$this->setAttribute('method', 'post');
$this->add(array(
'type' => 'AlbumModule\Form\newAlbumFieldset',
'options' => array(
'use_as_base_fieldset' => true
)
));
$this->add(array(
'name' => 'submit',
'attributes' => array(
'type' => 'submit',
'value' => 'go'
),
));
}
}
请求ajax调用 -
Request URL:http://test/newAlbum.html
Request Method:POST
Status Code:200 OK
Request Headersview source
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:46
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
Cookie:PHPSESSID=h46r1fmj35d1vu11nua3r49he4
Host:test
Origin:http://test
Referer:http://test/newAlbum.html
User-Agent:Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36
X-Requested-With:XMLHttpRequest
Form Dataview sourceview URL encoded
album[albumText]:hello world
submit:go
Response Headersview source
Connection:Keep-Alive
Content-Length:4139
Content-Type:text/html
Date:Sun, 20 Oct 2013 16:52:15 GMT
Keep-Alive:timeout=5, max=99
Server:Apache/2.4.4 (Win64) PHP/5.4.12
X-Powered-By:PHP/5.4.12
提交按钮的请求 -
Request URL:http://test/newAlbum.html
Request Method:POST
Status Code:200 OK
Request Headersview source
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:46
Content-Type:application/x-www-form-urlencoded
Cookie:PHPSESSID=h46r1fmj35d1vu11nua3r49he4
Host:test
Origin:http://test
Referer:http://test/newAlbum.html
User-Agent:Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36
Form Dataview sourceview URL encoded
album[albumText]:hello world
submit:go
Response Headersview source
Connection:Keep-Alive
Content-Length:4139
Content-Type:text/html
Date:Sun, 20 Oct 2013 16:52:14 GMT
Keep-Alive:timeout=5, max=100
Server:Apache/2.4.4 (Win64) PHP/5.4.12
X-Powered-By:PHP/5.4.12
这是控制器上的indexAction()的完整性 -
public function indexAction()
{
echo 'console.log("Index Action is Called");';
$form = new \AlbumModule\Form\newAlbumForm();
if ($this->getRequest()->isPost()){
echo 'console.log("Data posted");';
$form->setData($this->getRequest()->getPost());
if ($form->isValid()){
echo 'console.log("Form Valid");';
//todo
$this->forward()->dispatch('newAlbum', array('action' => 'submitAlbum'));
return new ViewModel(
array(
'form' => $form
)
);
} else {
echo 'console.log("Form Invalid");';
return new ViewModel(
array(
'form' => $form
)
);
}
} else {
echo 'console.log("No data posted")';
return new ViewModel(
array(
'form' => $form
)
);
}
}
正如我在开头所说的,当按钮提交表单时,isPost()
类将返回值true,但是当通过Ajax提交表单时,它将返回false值。
编辑 -
我已在下面发布了答案。
答案 0 :(得分:10)
通常当您从ajax发送数据时,您不需要再次渲染模板,这就是ViewModel所做的。
尝试将json策略添加到module.config.php
'view_manager' => array(
//other configuration
'strategies' => array(
'ViewJsonStrategy',
),
),
然后你的行动应该是这样的:
public function ajaxAction()
{
$request = $this->getRequest();
if ($request->isXmlHttpRequest()){ // If it's ajax call
$data = $request->getPost('data'));
...
}
return new JsonModel($formData);
}
答案 1 :(得分:4)
感谢SzymonM,我能够解决这个问题,
基本上,您似乎必须将操作作为 json 类型发布,这意味着您发布的任何控制器/操作都必须为jquery返回“成功”响应ajax调用也会返回成功。
因此,尝试发布到索引操作会产生问题,因为您尝试通过 viewModel 对象或 json 回复很多if语句。
最好的选择是将json请求发布到管理请求和响应的不同操作。
Ajax Action -
public function ajaxAction()
{
$form = new \AlbumModule\Form\newAlbumForm();
$request = $this->getRequest();
$response = $this->getResponse();
if ($request->isPost()) {
//$hello is a test variable used for checking if the form is valid
//by checking the response
$hello = 1;
$form->setData($request->getPost());
if ($form->isValid()){
$hello = 4020;
};
}
$messages = array();
if (!empty($messages)){
$response->setContent(\Zend\Json\Json::encode($messages));
} else {
$response->setContent(\Zend\Json\Json::encode(array('success'=>1,'hello'=>$hello)));
}
return $response;
}
Ajax Call-
var urlform = '<?php echo $this->url('AlbumModule\newAlbum\home', array('controller'=>'newAlbum', 'action'=>'ajax')); ?>';
$.ajax({
url: urlform,
type: 'POST',
dataType: 'json',
async: true,
data: $("#newAlbumForm").serialize(),
success: function (data) {
console.log(data);
}
error: function (data) {
console.log(data);
}
});
答案 2 :(得分:0)
最好的方法是使用
AcceptableViewModelSelector
控制器插件在不同策略之间切换
首先在module.config.php
中 return [
'view_manager'=>[
'Strategies'=> 'ViewJsonStrategy',
]
]
并在控制器示例中:indexAction
中的IndexController.phpclass IndexController extends AbstarctActionController{
protected $accptCretiria = [
'Zend\View\Model\ViewModel'=>'text/html',
'Zend\View\Model\JsonModel'=>'application/json, text/json'
];
public function indexAction(){
//here if is ajax call it returns jsonView ,and if is normal call it return ViewModel
$viewModel = $this->acceptableViewModelSelector($this->acceptCretiria);
return $viewModel
}
}
答案 3 :(得分:-1)
Zend Framework 2有一个名为WasabiLib的模块。它几乎掌握了以非常方便的方式管理ajax请求和响应的所有内容。看一下homepage上的简单示例,提供一个简单的表单:
//inside the phtml
<form id="simpleForm" class="ajax_element" action="simpleFormExample" method="POST"
data-ajax-loader="myLoader">
<input type="text" name="written_text">
<input type="submit" value="try it">
<i id="myLoader" class="fa fa-spinner fa-pulse fa-lg" style="display: none;"></i>
</form>
//Server-side code
public function simpleFormExampleAction(){
$postArray = $this->getRequest()->getPost();
$input = $postArray['written_text'];
$response = new Response(new InnerHtml("#element_simple_form","Server Response: ".$input));
return $this->getResponse()->setContent($response);
}