douliang9057
douliang9057
2013-10-20 17:06

使用Ajax将表单数据发布到ZF2控制器

已采纳

EDIT-
I have posted the answer below.

The question is that I don't understand how/where ZF2 posts form data when a submit button is pressed. So, when I do
if ($this->getRequest()->isPost()){
after the ajax call below, it tells me that no data has been posted.

When I do the above isPost() if statement it works perfectly when I hit the submit button, telling me the data has been posted and subsequently telling me that the form data is valid.

Here is the 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. 
                });

Here's the Form-

            use Zend\Form\Form;

            class newAlbumForm extends Form
            {
                public function __construct()
                {
                    parent::__construct('newAlbumForm');
                    $this->setAttribute('method', 'post');

                    $this->add(array(
                        'type' => 'AlbumModule\Form
ewAlbumFieldset',
                        'options' => array(
                            'use_as_base_fieldset' => true
                        )
                    ));

                    $this->add(array(
                            'name' => 'submit',
                                'attributes' => array(
                                    'type' => 'submit',
                                    'value' => 'go'
                        ),
                    ));
                }
            }



The request for the 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

The request for the submit button-

            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



Here is the indexAction() on the controller for completeness-

            public function indexAction()
            {
                echo 'console.log("Index Action is Called");';

                $form = new \AlbumModule\Form
ewAlbumForm();
                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
                            )
                        );
                }
            }

As I stated at the beginning, the isPost() class will return a value of true when the button submits the form, but it will return a value of false when the form is submitted through Ajax.

EDIT-
I have posted the answer below.

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

4条回答

  • dporb84480 dporb84480 8年前

    Usually when you send data from ajax, you don't need to render your template again, and that's what ViewModel do.

    Try to add json strategy to your module.config.php

    'view_manager' => array(
        //other configuration
        'strategies' => array(
            'ViewJsonStrategy',
        ),
    ),
    

    Then your action should look like this:

    public function ajaxAction()
    {
        $request = $this->getRequest();
    
        if ($request->isXmlHttpRequest()){ // If it's ajax call
            $data = $request->getPost('data'));
            ...
        }
    
    
        return new JsonModel($formData);
    }
    
    点赞 评论 复制链接分享
  • doujingtang6580 doujingtang6580 8年前

    Thanks to SzymonM I was able to figure this out,

    Basically, it seems that you HAVE to post to an action as type json, this means that whatever controller/action that you're posting to has to return a 'success' response for the jquery ajax call to also return success.
    So, trying to post to the index action creates problems as you would be trying to return viewModel objects or a json response through many if statements.
    The best option is to post the json request to a different action which will manage the request and response.

    Ajax Action-

    public function ajaxAction()
    {
        $form       = new \AlbumModule\Form
    ewAlbumForm();
        $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
    ewAlbum\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);
        }
    });
    
    点赞 评论 复制链接分享
  • duandou8457 duandou8457 6年前

    There is a module for Zend Framework 2 called WasabiLib. It has almost everything onboard to manage ajax requests and responses in a very convinient way. Take a look at the simple example on its homepage providing a simple form:

    //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);
    }
    
    点赞 评论 复制链接分享
  • doucong4535 doucong4535 6年前

    the best approach is to use the

    AcceptableViewModelSelector

    controller plugin to switch between different strategies

    first in module.config.php

     return [
         'view_manager'=>[
           'Strategies'=> 'ViewJsonStrategy',     
         ]
     ]
    

    and in the controller example: IndexController.php in the 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
            }
        }
    
    点赞 评论 复制链接分享

为你推荐