РЕДАКТИРОВАТЬ-
Я опубликовал ответ ниже.
Вопрос в том, что я не понимаю, как / где ZF2 публикует данные при нажатии кнопки отправки. Итак, когда я это делаю
if ($this->getRequest()->isPost()){
после вызова ajax ниже, он сообщает мне, что данные не были опубликованы.
Когда я делаю вышеуказанный isPost()
if, он отлично работает, когда я нажимаю кнопку « isPost()
, сообщая мне, что данные были опубликованы, и впоследствии сообщив мне, что данные формы действительны.
Вот ajax call-
<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 call-
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, когда кнопка отправит форму, но вернет значение false, когда форма будет отправлена через Ajax.
РЕДАКТИРОВАТЬ-
Я опубликовал ответ ниже.
Обычно, когда вы отправляете данные из 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); }
Благодаря 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); } });
наилучшим подходом является использование
AcceptableViewModelSelector
плагин контроллера для переключения между различными стратегиями
сначала в module.config.php
return [ 'view_manager'=>[ 'Strategies'=> 'ViewJsonStrategy', ] ]
и в примере контроллера: IndexController.php в indexAction
class 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 } }
Существует модуль для Zend Framework 2 под названием WasabiLib. У него есть почти все, что нужно для управления запросами и ответами ajax очень удобным способом. Взгляните на простой пример на своей домашней странице, предоставив простую форму:
//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); }