Чистая реализация контроллера Ajax в Zend Framework - PullRequest
4 голосов
/ 15 августа 2011

Мне нужен контроллер в моем проекте 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. Так вот почему я спрашиваю, как сделать это по-зендски?

Первое, о чем я подумал - создать плагин контроллера, но как мне легко зарегистрировать этот плагин? Бутстрап не вариант, потому что это нужно только для определенных контроллеров. И зарегистрировать его внутри контроллера в очень раннем состоянии кажется не очень чистым.

Так как мне реализовать мой контроллер Ajax? Я также знаю, что есть расширенный помощник по переключению контекста, однако я думаю, что в этом случае слишком много служебной информации для установки типа контента и т. Д.

Ответы [ 4 ]

4 голосов
/ 20 сентября 2011

markus объяснил самый "Zend Like" способ, и его объяснение верно.Но вы считаете это слишком большими затратами, потому что он упустил возможность показать вам, насколько «переключение контекста json» является лучшим для вашего случая.

Посмотрите, насколько оно короткое:

//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
3 голосов
/ 16 августа 2011

Вы можете просто использовать

$this->_helper->json($data);

где угодно. Он отключает все ненужное, очищает ответ, кодирует данные в json, отправляет ответ и устанавливает заголовки пропппера в качестве бонуса . Я думаю, это самый «зенд-путь»;)

2 голосов
/ 15 августа 2011

Содержимое нужно переключать, только когда вы на самом деле вызываете действие ajax.Я думаю, что Zend-путь - это хороший путь.Это очень гибкий и простой в реализации.В большинстве случаев для разных контроллеров потребуется пара действий ajax.Я не вижу необходимости или преимущества чистого контроллера ajax.

Каждый контроллер может иметь что-то подобное в init ():

$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContext('some-toggle', 'html');
$ajaxContext->addActionContext('some-other-ajax-thing', 'json');
$ajaxContext->initContext();

Действие выглядит как любой другойдействие.Скрипт представления имеет только одну переменную типа:

<?php echo $this->response; ?>

... и должен называться actionname.ajax.phtml.

Затем, если вы нажимаете дополнительные действия на свое действиестек, это нужно делать только для не-AJAX-запросов, например:

if (!$request->isXmlHttpRequest())
{
    //push actions on stack
}

Кроме того, вы должны передать параметр формата вместе с URL-адресом поста AJAX, например posturl/format/html или posturl/format/json.

1 голос
/ 15 августа 2011

Я сделал то же самое, что и вы, у меня есть контроллер, специально предназначенный для обработки ajax-запросов, однако мое решение намного проще, я использовал функцию 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, то это может быть вариант для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...