I\'m going to start a project using a Zend Framework MVC implementation.
How do I work with ajax? I mean, should I place all ajax code into controller? Or into view?
Take a look at the AjaxContext Action-Helper (or the ContextSwitch one, which it extends), and it will allow you to use exactly the same controller code, switching to either a separate view-script (foo.json.phtml, or foo.ajax.phtml etc. - picked up automatically from a ?format parameter), or make use of the JSON Action-Helper that will return an object comprising all the variables you assign to the view - so you don't need to be echoing from your controller (which will mess up unit-tests, should you have them).
When i use ajax with codeigniter i output straight out of the controller.
I also use seperate controller for simple ajax requests like flagging, favorites, etc. For ajax requests like login, contact, etc i would add logic to the normal path(eg. domain.com/contact) do deal with an ajax request. I then output json and kill script execution.
You really should read the manual chapter about ContextSwitch Action Helper. But here is a brief outline:
To switch between these two contexts you have to add a format parameter to your URL, e.g. /posts/author/ivan/format/json or /posts/author/ivan/format/xml. If you do not specify the format your application will output plain html.
Special version of the Context switch is AjaxContext and you also have to configure this one by hand. It does not use the 'format' parameter to identify which format it should use for output but it examines the header sent in your request and looks for 'X-Requested-With: XmlHttpRequest' header and if it is present the AjaxContext is examined. Using the AjaxContext action helper you can specify which context should be used for specific actions if the request is fired using AJAX.
You can utilize the same actions to return XML, JSON or whatever, by detecting ajax requests and thus being able to differentiate ajax requests from normal ones. For example:
public function fooAction()
{
if($this->getRequest->isXmlHttpRequest()) {
echo json_encode($someData);
} else {
echo 'This is the normal output';
}
}
Your View can be something other than HTML, and either the pipeline can react to the request being an ajax post, or your controller can react. Either way, it should be as simple as return a different View.
My syntax might be older but this a sketch of my REST action from my Index Controller:
/**
* REST Action for this application.
*
* @return void
*/
public function restAction()
{
$this->_helper->viewRenderer->setNoRender(true);
$parameters = (func_num_args() > 0) ? array($key => func_get_arg(0)) : $this->getRequest()->getParams();
$key = 'restCommand';
if(!array_key_exists($key, $parameters)) throw new Exception('Request for “' . $key . '” not found.');
$restCommand = $parameters[$key];
$xmlString = IndexModel::getEmptyXmlSet($restCommand);
$xslFile = IndexModel::getModelFilePath('index');
//Handle OPML-driven REST commands:
if(stripos($restCommand, 'opml-') === 0)
{
$opmlCall = explode('-', $restCommand);
if(count($opmlCall) != 3)
{
$xmlString = Songhay_SimpleXml::getXmlMessage('OPML Call Not Recognized', array('The number of parameters are incorrect.'));
}
else
{
$opmlSet = $opmlCall[1];
$opmlId = $opmlCall[2];
$xmlString = IndexModel::getRssFragmentWithOpml($opmlSet, $opmlId);
}
}
//Handle general REST commands:
switch($restCommand)
{
case 'deeplink':
$key = 'id';
if(!array_key_exists($key, $parameters)) throw new Exception('Request for “' . $key . '” not found.');
$url = $parameters[$key];
$xmlString = IndexModel::getRssFragment($url);
$xmlString = Songhay_SimpleXml::loadXslString($restCommand, $xmlString, $xslFile);
break;
case 'index':
$opmlFile = IndexModel::getModelFilePath('index', '.xml');
$xmlString = Songhay_SimpleXml::loadXmlAndStripNamespaces($opmlFile);
$xmlString = Songhay_SimpleXml::loadXslString($restCommand, $xmlString, $xslFile);
break;
default:
$xmlString = Songhay_SimpleXml::loadXslString($restCommand, $xmlString, $xslFile);
}
$response = $this->getResponse();
$response->setHeader('Content-Type', 'text/xml');
$response->setBody($xmlString);
return;
}