AJAX в Zend Framework

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

Поделиться в соц. сетях

Опубликовать в Google Plus
Опубликовать в LiveJournal

Похожие посты:

  1. Новая версия Zend Framework — 1.7
  2. Пример использования ArrayAccess

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>