Using ajax in zend framework 2

2019-04-09 03:20发布

问题:

i am really new to the zend framework 2 and to the programming of web applications. In my application, i want to have a button which triggers a function that changes the content of a database and returns a String which i can use to update the visible content of the website. As i don´t want the website to reload when the button is clicked, i would like to do this using ajax. After reading a couple of ajax tutorials, i imagined that the solution would look somilar to this:

The HTML part:

 <head>

 <script type="text/javascript">

 function myFunction() {

var xmlhttp = new XMLHttpRequest();
    // I am working with Chrome

    xmlhttp.onreadystatechange=function(){

        if (xmlhttp.readyState == 4 && xmlhttp.status == 200){

                var text = xmlhttp.responseText;
        document.getElementById("text_paragraph").innerHTML =                 
                            text;
            }
                    };

        xmlhttp.open("GET", "function.php", true);
        xmlhttp.send();

}

 </script>

 </head>

 <body>
 ......
 <button id="function_button" onClick="myFunction()">Click</button>
 <p id = "text_paragraph">Initial text"</p>
 ......  
 </body>

With the .php file function.php (for the beginning, i just want it to return a text value) :

<?php

     echo "Text triggered by the button click";
?>

When i try to test the button, nothing happens. Apparently, the xmlhttp.status is 404 and the function.php file can´t be found. I suppose that either the location where i put the function.php file (it is in the same folder as the .phtml - view file of the website) or the url i´m using in the xmlhttp.open - function is wrong. Could you please tell me how to use ajax in zf2 correctly? Thank you for your time, every answer is very much appreciated.

回答1:

First of all i want to thank for all your answers. They really were a great help. Using jQuery is indeed much more comfortable, and not only for Ajax calls, than using pure Javascript. James, thank you very much for your answer. I tried to use it, but i probably did something wrong because it did not work. I found another solution for my problem and i want to post it here in order to round this question up.

The code that i am going to post is a little example that just does a simple thing: on a user click on a button in a website created by zend framework 2, an input field is read, the content of it is transfered to a server function, which, according to the data it receives, returns a certain result. After receiving the result, the website is updated without being reloaded.

As i am going to use Json objects for the communication, it is necessary to activate the Json strategies in zf2 by adding the following codeline to the module.config.php:

// module/Application/config/module.config.php

'view_manager' => array (
                'display_not_found_reason' => true,
                'display_exceptions' => true,
                'doctype' => 'HTML5',
                'not_found_template' => 'error/404',
                'exception_template' => 'error/index',
                'template_map' => array (
                        'layout/layout' => __DIR__ .   
'/../view/layout/layout.phtml',
                        'application/index/index' => __DIR__ . 
'/../view/application/index/index.phtml',
                        'error/404' => __DIR__ . 
'/../view/error/404.phtml',
                        'error/index' => __DIR__ . 
'/../view/error/index.phtml' 
                ),
                'template_path_stack' => array (
                        __DIR__ . '/../view' 
                ),
                'strategies' => array (            // Add
                                           // this
                        'ViewJsonStrategy' // line
                )

        ),

The view file of the website (called, for example example.phtml) will look similar to this:

<html>
<head>

<script
    src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>

<script>

//Function,  activated by clicking the button

$("#trigger").click(function(){

    var text = $("#input_to_read").val();
    var myData = {textData:text};

    //The post using ajax
    $.ajax({
            type:"POST",
            // URL : / name of the controller for the site / name of the action to be                         
            //                                                 executed
            url:"/example/answer",
            data:myData,
            success: function(data){
                                   //The callback function, that is going to be executed 
                                   //after the server response. data is the data returned
                                   //from the server.

                                   // Show the returned text
                                   $("#answer").text(data.text);


                                    },
            failure(function(){alert("Failure!!");})


           });


});


</script>
</head>

<body>

<input id="input_to_read" type="text">
<button id="trigger">Klick</button>
<!-- The answer will be shown here. -->
<p id="answer"></p>
</body>
</html>

The server function, that is going to be called when the button is clicked, is placed in the controller for the website (in this case, the ExampleController) and could look like this:

//Make sure to add this line to use Json objects
use Zend\View\Model\JsonModel;

....


public function answerAction(){

#read the data sent from the site
$text = $_POST['textData'];

#do something with the data

$text = $text . "successfully processed";

#return a Json object containing the data

$result = new JsonModel ( array (

                'text' => $text 
        ) );
return $result;
}


回答2:

Typically the way I would handle this, is to build an RPC controller to just return JSON, and then use some good javascript frameworks like jQuery, and Knockout JS, to dynamically update the relevant UI areas. I believe the base Zend controller class provides a $this->_helper->json method that will return JSON instead of returning what you have defined in a given view. In the case of Public_RpcController below I didn't even define a view at all. It returns JSON which I can use in conjunction with JS frameworks for client side markup manipulation. Using the JS frameworks has a bit of learning curve but well worth learning.

class Public_RpcController extends MySubClassed_Controller_Action
{
    public function getUserDataAction()
    {
        $output = array();
        $request = $this->getRequest();

        ...

        $output = array(
                'Value1'    => "foobar",
                'Value2'    => "foobar",
        );
        return $this->_helper->json($output);       
    }   
}

// Use Jquery to fetch JSON data to update. 
$.getJSON( "/rpc/get-user-data", function( data ) { 
    // Do something with the JSON data like bind to Knockout template.
});