Мне нужен контроллер в моем проекте Zend Framework, который должен обрабатывать только запросы ajax.
Мой подход на данный момент заключается в расширении Zend_Controller_Action:
class Ht_Ajax_Controller extends Zend_Controller_Action{ public function preDispatch(){ $this->getResponse()->setHeader('Content-type', 'text/plain') ->setHeader('Cache-Control','no-cache'); $this->_helper->viewRenderer->setNoRender(true); $this->_helper->layout()->disableLayout(); } public function outputJson($data){ $this->getResponse()->setBody(json_encode($data)) ->sendResponse(); exit; } }
Хотя, я знаю, что это не рекомендуемый способ сделать это в Zend Framework. Вот почему я спрашиваю, как это сделать в Zend?
Первое, о чем я думал, это создать плагин контроллера, но как я могу легко зарегистрировать этот плагин? Бутстрап не является вариантом, потому что мне это нужно только для определенных контроллеров. И зарегистрировать его внутри контроллера в очень раннем состоянии кажется не очень чистым.
Итак, как мне реализовать свой контроллер Ajax? Я также знаю, что есть расширенный помощник переключения контекста, однако я думаю, что у него слишком много накладных расходов для настройки содержимого контента и т. Д.
Маркус объяснил наиболее «Zend Like», и его объяснение правильное. Но вы видите, что это слишком много накладных расходов, потому что он пропустил, чтобы показать вам, насколько «json context switch» является лучшим для вашего дела.
Посмотрите, насколько это коротко:
//In your controller, activate json context for ANY called action in once public function init(){ $action = $this->_getParam('action'); $this->_helper->getHelper('contextSwitch') ->addActionContext($action, 'json') ->initContext(); }
И все , вам не нужны никакие сценарии просмотра, все переменные, которые вы назначаете через $this->view
будут сериализованы в объект JSON.
О, и вы не хотите добавлять контекст в URL? Ок, просто активируйте его по умолчанию на своем маршруте
routes.ajax.route = '/ajax/:action/*' routes.ajax.defaults.controller = ajax routes.ajax.defaults.action = index routes.ajax.defaults.format = json
Вы можете просто использовать
$this->_helper->json($data);
где угодно. Он отключает все, что не нужно, очищает ответ, кодирует данные в json, отправляет ответ и устанавливает заголовки propper в качестве бонуса . Это самый «zend-way», я думаю;)
Содержимое нужно переключать только тогда, когда вы на самом деле вызываете действие ajax. Я думаю, что путь Zend – хороший способ. Он очень гибкий и прост в реализации. В большинстве случаев разные контроллеры будут нуждаться в нескольких действиях ajax. Я не вижу необходимости или преимущества чистых контроллеров ajax.
Каждый контроллер может иметь что-то подобное в init ():
$ajaxContext = $this->_helper->getHelper('AjaxContext'); $ajaxContext->addActionContext('some-toggle', 'html'); $ajaxContext->addActionContext('some-other-ajax-thing', 'json'); $ajaxContext->initContext();
Действие выглядит как любое другое действие. Скрипт вида имеет только один var:
<?php echo $this->response; ?>
… и должен называться actionname.ajax.phtml.
Затем, если вы нажимаете дополнительные действия на свой стек действий, вам нужно сделать это только для запросов без аякса, например:
if (!$request->isXmlHttpRequest()) { //push actions on stack }
Кроме того, вам необходимо передать параметр формата вместе с URL-адресом ajax, например posturl/format/html
или posturl/format/json
.
Я сделал то же самое, что и вы, у меня есть контроллер специально для обработки аякс-запросов, однако мое решение намного проще, я использую функцию init (), а не preDispatch.
Моя функция init () выглядит так:
class Ajax_Controller extends Zend_Controller_Action { public function init() { $this->_helper->layout()->disableLayout(); } //the rest of the controller... }
Это оно! Я не сделал никаких других изменений со стандартного контроллера.
Я отключил визуализацию представления в действии, если это необходимо, когда я нашел, в моем случае мне понадобилось представление для рендеринга таблиц и т. Д. Однако, если вы только когда-либо возвращаете данные json, тогда ваш метод отключения рендеринга представлений в preDispatch () отлично действует ,
Если мне нужно вернуть json, у меня есть аналогичная функция для вас, и я отключу отображение рендеринга.
Я использовал этот метод на 4 отдельных, но похожих проектах без каких-либо проблем. Сказав, что мои вызовы ajax обычно довольно просты, но я не вижу никаких проблем с этим методом.
Если вы ищете простую, чистую реализацию ajax, то это может быть для вас вариантом.