Издавно у меня выработалась привычка писать приложения так, чтобы они могли с лёгкостью работать и через AJAX и как его сейчас называют HMVC. При этом самое важное условие — изменения в коде контроллеров не должно быть вовсе или они должны быть минимальны. На самом деле будет написано об AJAH, потому что общение идёт через html, а не xml, но AJAX более привычное название, поэтому ниже буду использовать его.
Для начала нам нужен двухшаговая шаблониция, когда в начале генерируется основной контент, а затем он вставляется в мастер шаблон. В ZF для этого есть layouts. Подключаем их в конфиге
resources.layout.layoutPath = APPLICATION_PATH «/layouts/scripts/»
При этом будет по дефолту рентериться layout.phtml. У себя я практикую подмену мастер шаблона на ajax.tpl.php, в ZF это можно сделать через плагины или бутстрапы, но они меня пугают своей кривой документацией и примеры из мануала зачастую не работают. Можно использовать смену контекста AjaxContext, но опять же у меня возникли проблемы, да и это не очень мне нравится. Поэтому, следуя принципу KISS, я решил наговнокодить прямо в основном лэйауте.
<?php /* @var $this Zend_View */ ?>
<?php $request = Zend_Controller_Front::getInstance()->getRequest();
if ($request->isXmlHttpRequest()) { ?>
<?php echo $this->layout()->content; ?>
<?php } else { ?>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<?php echo $this->jQuery(); ?>
<script type="text/javascript">
$(function() {
$("a.ajax").live('click', function() {
var conteiner = $(this).attr('ajax-container').toString();
if (!conteiner) {
conteiner = '#container';
}
var $container = $( conteiner );
$container.load(this.href);
return false;
});
$dialog = $( "#dialog" );
$("a.ajax-modal").live('click', function() {
$dialog.hide().load(this.href).dialog({
width: 800,
position: 'top',
modal: true
});
return false;
});
$('#form-conteiner form').live('submit', function() {
$dialog.html('Загрузка...');
$.post(this.action, $(this).serialize(), function(data) {
$dialog.html(data);
});
return false;
});
})
</script>
</head>
<body>
<div id="dialog" style="display: none;"></div>
<section id="container">
<?php
$partial = array('menu.phtml', 'default');
$this->navigation()->menu()->setPartial($partial);
echo $this->navigation()->menu();
?>
<?php echo $this->layout()->content; ?>
</section>
</body>
</html>
<?php } ?>
Пройдёмся по коду. В начале шаблонов я пытаюсь организовать хоть какой автокомплит подсказав IDE что $this — это Zend_View и благодаря этому получил подсказки на публичные методы, хотя можно использовать protected и private, но на безрыбье и рак — рыба.
Затем спрашиваем у реквеста на AJAX ли запрос $request->isXmlHttpRequest(), благо это zf умеет, а фича определяется на основании заголовков.
Собственно для AJAX нам нужно выплюнуть тупо часть нагенерированную экшином <?php echo $this->layout()->content; ?>, а для обычных запросов отдаём как положено c head, меню и т.д.
На этом можно было бы заканчивать повествование, т.к. теперь всё можно запрашивать через AJAX, но раскажу о парочке строк js.
<?php echo $this->jQuery(); ?> — это подключение jQuery, для этого используется библиотека ZendX, которая является не обязательной, поэтому можно вручную прописать пути к jQuery и jQuery UI, это будет даже более KISS.
Теперь вешаем на ссылки с классом »ajax» запросы AJAH. По умолчанию всё будет грузиться в div#conteiner, но для удобства можно прописывать другой контейнер в атрибуте ссылки ajax-container, указав в нём jquery селектор, например, ajax-container=»#conteiner» или container=»#conteiner2″. Так же можно выводить в модальном окне, указав класс ajax-modal.
Формы я заварачиваю в div <div id=»form-conteiner»> и прописываю хук, чтобы он перехватывал обработчик отправки и отсылал форму AJAX-ом.
$('#form-conteiner form').live('submit', function() {
$dialog.html('Загрузка...');
$.post(this.action, $(this).serialize(), function(data) {
$dialog.html(data);
});
return false;
});
Данное решение имеет большой минус — загрузка файлов, поэтому для таких вещей лучше заворачивать форму в iframe. Второй минус — закрытие окна после загрузки. Для этого нужно возвращать строку js для закрытия диалога или обновления страницы.
<script>$('#dialog').dialog('close')</script>
<script>location.href='/new/url/'</script>
Я обычно не делаю формы на ajax. При том, что всё может работать на AJAX буквально одной строкой кода, но предпочитаю олдскульные перезагрузки, без геморроя с утечками, файлами, сохранением URL и history. Будь осторожны, не злоупотребляйте.
P.S. Очень хотелось бы услышать критику и советы как нужно делать. Потому как я после выхода ZF 1.0 забил на него и лишь занимался доработкой проектов, а сейчас впервые начал делать с нуля и делаю всё по старинке, подходом который использую в своём фреймворке. Так что учите меня.
Поделиться в соц. сетях
Похожие посты: