Итак, приступим к продолжению нашей интеграции AJAX и Zend Framework. Начнём с того, что планы несколько изменились – изначально я планировал разбить статью на три части, во второй части рассказав про работу с Zend_Form применительно к AJAX’у. Начав писать статью я понял, что рассказывать там решительно нечего – работа с AJAX’ом применяя Zend_Form не имеет каких-либо серьёзных особенностей.
Сейчас вы узнаете про хэлпер AjaxContext, делающий нашу работу с AJAX’ом ещё удобнее и проще.
Первая часть статьи
Часть 2. Работа с хэлпером AjaxContext
Хэлпер (помощник, helper) – это интегрированный в один из компонентов фреймворка (в нашем случае, в Zend_Controller_Action) класс, помогающий нам выполнять какие-то определённые действия. Подробнее о них вы можете почитать в документации
Принцип действия хэлпера AjaxContext заключается в том, что он заменяет шаблон вида на нужный нам формат вывода. Подробности его работы вы можете узнать, опять же, в документации,
а мы будем знакомиться с основами его работы на конкретном примере.
Помните, в чём заключался основной принцип работы в первой части статьи? Мы отслеживали AJAX-запросы, отключали автоматический рендеринг скриптов вида, и вручную выводили JSON-кодированные данные.
В этот раз мы поступим умнее:
1 2 3 4 5 | public function init() { //активируем хэлпер AjaxContext //и передаём туда имя action'а, который необходимо интегрировать с AJAX'ом $this->_helper->AjaxContext()->addActionContext('login', 'json')->initContext('json'); } |
Что делает этот хэлпер. В первую очередь, он отслеживает ajax-запросы и отключает для них авторендеринг скриптов вида. Затем, после выполнения action’а, хэлпер кодирует все данные, переданные в наш view-класс, кодирует их в формат JSON и выводит на экран (т.е. передаёт браузеру). Таким образом, нам больше не нужно задумываться на стороне сервера о том, откуда поступил запрос и как его нужно обработать, это всё перекладывается на плечи разработчиков клиентской части скрипта.
Вот наш переработанный action:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | public function loginAction() { //проверяем, были ли посланы логин и пароль if (($login = $this->_getParam('login')) && ($password = $this->_getParam('password'))) { //наш воображаемый класс авторизации $loginClass = new loginClass($login, $password); //проверяем валидность $result = $loginClass->isValid() ? 'success' : 'error'; //если авторизация прошла успешно - в errors записываем пустой массив //иначе - получаем сообщения ошибкок $errors = 'success' == $result ? array() : $loginClass->getErrors(); if ('success' == $result && !$this->getRequest()->isXmlHttpRequest()) { //авторизация успешна - делаем редирект //если аякс - редирект нам не нужен :) $this->_redirect('/'); } //передаём результаты в шаблон $this->view->errors = $errors; $this->view->result = $result; } } |
Теперь в случае ajax-запроса мы получим JSON-кодированные данные, а если запрос будет обычным – будет выведен обыкновенный шаблон.
Anton Shevchuk says:
Для реализации AJAX’a в ZF использую бибилотеку jQuery-PHP, используя ее нет необходимости писать еще один хэлпер, достаточно использовать существующий Url (хотя с помощью хэлпера можно упростить синтаксис)…
10 июня 2008, 9:44guest says:
Спасибо большое за информацию. Как раз осваиваю зенд.
21 июня 2008, 17:06Hinikato says:
Полезно, спасибо за статью
10 ноября 2008, 16:48Не пользовался этим хелпером, заюзаю, посмотрю.
Berkut says:
Прикольная штучка! Сейчас попробую=). Огромное спасибо!!!
20 ноября 2008, 10:03Alexander says:
В случае работы в ajax контексте контроллер как обычно выдаст данные во вьюху, которая будет частью лэйаута, т.е. мы подцепим лишние данные, такие как заголовки страницы.
20 ноября 2008, 12:32Как заставить контроллер отдавать действие сразу на вьюху минуя лэйаут?
Сергей Митрошин says:
Вообще-то ajaxContext должен автоматически отключать layout. Если это по каким-либо причинам не произошло, то надо вручную вызывать статичный метод Zend_Layout::disableLayout().
20 ноября 2008, 12:37Alexander says:
Спасибо
20 ноября 2008, 12:38Сергей Митрошин says:
Можно даже добавить callback-метод для AjaxContext, в котором и вызывать disableLayout().
20 ноября 2008, 14:44Alesksey says:
Спасибо, как всегда полезная статья.
1 мая 2009, 11:46А отключить layout можно еще так:
Zend_Controller_Action_HelperBroker::getStaticHelper(‘layout’)->disableLayout();
Baron says:
Сори, но я уже просто вешаюсь. РАботаю в Zend Studio. Скачал библиотеку jquery. Открыл в студии и в ней куча ошибок, при подключении файла на старнице, сразу сыпиться куча ошибок. И это без написания кода js. я вообще без понятия что делать. достал этот маразм… и нигде никакой информации по такому случаю… вот пишу вам – вдруг поможете
23 июля 2009, 8:24Baron says:
нихера и ничего не работает….. супер примеры…. студия все что можно только перечеркнула и подчеркнула
23 июля 2009, 21:41Atapin says:
есть такой вопрос.
есть три поля select
при выборе первого id=library
происходит загрузка naviAction
$(“#library”).change(function() {
$(“#book”).load(“navigation/navi”, { id: $(“#library”).val() });
});
если вывод делать в ISON тогда не ясно как имя переменной, которую потом декодировать,
если вывод делать в html то дублируется объект (помещается один в один)
если не трудно, посоветуйте
12 октября 2009, 4:29Atapin says:
ах да,
12 октября 2009, 4:32вывод в json делаю так:
public function init() {
$this->_helper->AjaxContext()->addActionContext(‘navi’, ‘json’)->initContext(‘json’);
}
Atapin says:
к тому же, измененный объект уже не отправляет данные по событию change
12 октября 2009, 5:48хотя Firebug показывает его.
Atapin says:
вот тут можно посмотреть http://bq.igmission.net/
12 октября 2009, 6:27Jully says:
Все замечательно, только вот отрабатывает у меня как-то неправильно:
вместо готового html-куска, посылается объект(структура) с данными запрашиваемого экшена.
Если этот экшен вызываю напрямую (из строки браузера) – то он конечно же отрабатывает и отображается в соотвествии с заданным шаблоном….
18 декабря 2009, 23:28Jully says:
class ChecknameController extends Basic_Controller{
public function preDispatch(){
parent::preDispatch();
$this->_helper->layout()->disableLayout();
$this->_helper->AjaxContext()->addActionContext(‘index’, ‘json’)->initContext(‘json’);
}
public function indexAction(){
……
$this->view->result = SOME_VAL;
}
где-то на странице вызываем такую js-ф-ию:
function checkName(name, type){
18 декабря 2009, 23:53$.get(
‘/checkname’,
{ name: name, type: type },
function(data) {
var targetDiv = document.getElementById(“nameCheck”);
targetDiv.innerHTML = data;
}
);
Jully says:
конструкция такого вида
$(“#nameCheck”).load(‘/checkname’, { name: name, type: type });
так же дает прежний результат.
такое ощущение, что по каким-то соображениям до обработки view дело не доходит.
а вижу я структур вида:
{“project”:”__NONE__”,”controller”:”checkname”,”area”:”checkname”,”action”:”index”,”result”:false}
19 декабря 2009, 0:14Oleg says:
Спасибо за мануал. Только вопрос. Для какой версии ZF это писалось?
19 июня 2010, 21:48oleg says:
Спасибо, помогло
10 сентября 2010, 18:02cmygeHm says:
Если имя Action’а содержит два слова и второе начинается с большой буквы, то у меня вылетает ошибка что такой экшен не существует.
Как быть?
Например для экшена с именем generateReportAction.
21 октября 2010, 13:23Bob says:
Здравствуйте!
Интересная статья, попробовал сделать, но не получается…
основная проблемма
—————————
$this->getRequest()->isXmlHttpRequest() – ничего не возвращает
—————————
кусочек моего вида (пробовал по всякому)
……….
function submitform(login, password)
{
//посылаем наш аякс-запрос
$.ajax({
url:’http://полный путь к скрипту (назвал его login2)’,
type: ‘POST’,
dataType: “json”,
{ login: login, password: password },
success: function(response){
alert(‘Данные отправлены! Сервер вернул ответ: ‘ + response);
}
error: function(response){ alert(‘Данные отправлены! Сервер вернул ответ: ‘ + response);}
complete: function(response){ alert(‘Данные отправлены! Сервер вернул ответ: ‘ + response);}
});
}
…………….
тут без изменений
помогите выяснить плиз, почему $this->getRequest()->isXmlHttpRequest() – ничего не возвращает
спасибо, надеюсь решение поможет и другим, кто столкнулся с такой проблеммой
10 августа 2011, 16:27cmygeHm says:
Боб! добавь data:
dataType: “json”,
12 августа 2011, 14:55data: { ‘login’: login, ‘password’: password }
Bob says:
dataType: “json” – не работает,(переда)
15 августа 2011, 14:14dataType: “html” – работает!
хотел бы научится передавать “json”
где здесь собака зарыта ?
123 says:
$this->_helper->AjaxContext()->addActionContext(‘login’, ‘json’)->initContext(‘json’);
а вид кто будет оключать?
AjaxContext():
Выключает макеты, если они включены.
Устанавливает альтернативный суффикс вида, это позволяет эффективно разделять скрипты видов для различных контекстов.
Отправляет HTTP-заголовки ответа, требуемые в данном контексте.
Опционально вызывает предопределенные функции обратного вызова для установки контекста и/или пост-обработки.
23 августа 2011, 18:42